《大话数据结构》笔记之 第三章 线性表

线性表的基本操作(一) 线性表的基本操作线性表的定义 线性表是具有相同特性数据元素的一个有限序列。该序列中所含元素的个数叫做线性表的长度(n)。注意:n可以等于0,表示线性表是一个空表。空表也可以作为线性表。线性表可分为顺序表和链表,本篇文章中以顺序表为主。 1.顺序表的结构定义#define maxSize 100 typedef struct{ int data[maxSize];//存放顺序表元素的数组 阅读详情

一、线性表的定义

1、线性表:零个或多个具有相同类型的数据元素的有限序列。元素之间是有顺序的,若元素存在多个,则第一个元素无前驱,最后一个元素无后继,其他每个元素都有且只有一个前驱和后继;且线性表强调是有限的。

2、线性表数学定义:若将线性表记为(a1,...,ai-1,ai,ai+1,...,an),则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。当i=1,2,...,n-1时,ai有且仅有一个直接后继,当i=2,3,...,n时,ai有且仅有一个直接前驱,如下图。所以线性表元素的个数n(n>=0)定义为线性表的长度,当n=0时,称为空表。

3、在非空表中的每个数据元素都有一个确定的位置,比如ai是第i个数据元素,称i为数据元素ai在线性表中的位序。

4、在较复杂的线性表中,一个数据元素可以由若干个数据项组成。

5、线性表的每个数据元素的类型都相同。

二、线性表的顺序存储结构

1、线性表的顺序存储结构指的是用一段地址连续的存储单元依次存储线性表的数据元素。如下图。所以可以用C语言的一维数组来实现顺序存储结构。

2、若采用数组来实现线性表的顺序存储结构,则数组的长度是存放线性表的存储空间的长度,存储分配后这个量一般是不变的;线性表的长度是线性表中数据元素的个数,随着线性表插入和删除操作的进行,这个量是变化的。在任意时刻,线性表的长度应该小于等于数组的长度。

3、地址计算方法:线性表不像数组那样起始下标是0,而是1。如下图。

      假设线性表每个数据元素占用的是c个存储单元,所以对于第i个数据元素ai的存储位置可以由a1推算得出,如下图,其中LOC表示获得存储位置的函数。通过这个公式,可以算出线性表中任意位置的地址,不管是第一个还是最后一个都是相同的时间,所以对每个线性表位置的存入或取出数据,对于计算机来说都是相等的时间,也就是一个常数,所以用算法的时间复杂度来说,它的存取时间性能为O(1)。通常把具有这一特点的存储结构称为随机存取结构。

4、采用C语言的一维数组来实现线性表的顺序存储结构,定义结构代码如:

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 20 /* 存储空间初始分配量 */

typedef int Status;          /* Status是函数的返回类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;        /* ElemType类型根据实际情况而定,这里假设为int */

typedef struct
{
	ElemType data[MAXSIZE];        /* 数组,存储数据元素 */
	int length;                                /* 线性表当前长度 */
}SqList;

5、获得元素操作:获取线性表的第i个位置的元素,就是把数组第i-1下标的值返回即可。实现代码如下:

/* 初始条件:顺序线性表L已存在,1≤i≤当前线性表的长度 */
/* 操作结果:用e返回L中第i个数据元素的值,注意i是指位置,第1个位置在数组中是从0开始 */
Status GetElem(SqList L, int i, ElemType *e)
{
    if(L.length == 0 || i < 1 || i > L.length)
    {
	return ERROR;
    }

    *e = L.data[i-1];
    return OK;
}

6、插入操作:线性表的顺序存储结构在插入数据时的实现过程如下图:

     插入算法的思路:

     1)如果插入位置不合理,抛出异常;

     2)如果线性表长度大于等于数组长度,则抛出异常或动态增加容量;

     3)如果插入位置不在表尾,从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置;

     4)将要插入元素填入位置i处;

     5)表长加1。   

     实现代码如下:

/* 初始条件:顺序线性表L已存在,1≤i≤当前线性表的长度+1*/
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(SqList *L, int i, ElemType e)
{ 
	int k;
	if (L->length == MAXSIZE)  /* 顺序线性表已经满 */
	{
		return ERROR;
	}
	if (i < 1 || i > L->length + 1)/* 当i比第一位置小或者比最后一位置后一位置还要大时 */
	{
		return ERROR;
	}
	if (i <= L->length)        /* 若插入数据位置不在表尾 */
	{
		for(k = L->length-1; k >= i-1; k--)  /* 将要插入位置之后的数据元素向后移动一位 */
		{
			L->data[k+1] = L->data[k];
		}
	}
        L->data[i-1] = e;          /* 将新元素插入 */
	L->length++;
	return OK;
}


7、删除操作:线性表的顺序存储结构删除元素过程如下图

 

    删除算法的思路:
     1)如果删除位置不合理,抛出异常;
     2)取出删除元素;
     3)如果删除元素不在表尾,从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置;
     4)表长减1。
     实现代码如下:

/* 初始条件:顺序线性表L已存在,1≤i≤当前线性表的长度 */
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
Status ListDelete(SqList *L, int i, ElemType *e) 
{ 
    int k;
    if (L->length == 0)               /* 线性表为空 */
	{
		return ERROR;
	}
    if (i < 1 || i > L->length)         /* 删除位置不正确 */
    {
		return ERROR;
	}    
    *e = L->data[i-1];
    if (i < L->length)                /* 如果删除不是最后位置 */
    {
        for(k = i; k < L->length; k++)/* 将删除位置后继元素前移 */
		{
			L->data[k-1] = L->data[k];
		}	
    }
    L->length--;
    return OK;
}


8、插入和删除的时间复杂度:最好情况是若元素插入到表尾,或删除最后一个元素,则时间复杂度为O(1),因为不需要移动元素。最坏情况就是元素要插入到第一个位置或删除第一个元素,则意味着要移动所有的元素向后或向前,所以时间复杂度为O(n)。至于平均的情况,由于元素插入到第i个位置,或删除第i个元素,需要移动n-i个元素,根据概率原理,每个位置插入或删除元素的可能性是一样的,也就是说位置靠前,移动元素多,位置靠后,移动元素少,但是最终平均移动次数和最中间的那个元素的移动次数相等,为(n-1)/2,所以,平均时间复杂度还是O(n)。所以:线性表的顺序存储结构,在读数据时,不管是哪个位置,时间复杂度都是O(1);而插入或删除时,时间复杂度都是O(n)。
9、线性表的顺序存储结构优缺点如下图。

三、线性表的链式存储结构
1、线性表链式存储结构定义:用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。这就意味着这些数据元素可以存在内存未被占用的任意位置。除了要存数据元素信息外,还要存储它的后继元素的存储地址。
2、为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息,把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称为指针或链。这两部分信息组成数据元素ai的存储映像,称为结点。
3、n个结点(ai的存储映像)链结成一个链表,即为线性表(a1,a2,...an)的链式存储结构,因为此链表的每个结点中只包含一个指针域,所以叫做单链表。单链表正是通过每个结点的指针域将线性表的数据元素按其逻辑次序链接在一起。如下图。

4、把链表中第一个结点的存储位置叫做头指针,整个链表的存取就必须是从头指针开始进行。
5、由于最后一个元素没有后继,所以线性链表的最后一个结点指针为空。
6、为了操作方便,可以在单链表的第一个结点前附设一个结点,称为头结点。头结点的数据域可以不存储任何信息,其指针域存储指向第一个结点的指针。如下图。

7、头指针与头结点的异同,如下图。

8、单链表的存储示意图。

    带有头结点:

    空链表:

9、用C语言的结构指针来描述单链表,如。

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */

struct Node
{
    ElemType data;
    struct Node *next;
};
typedef struct Node *LinkList; /* 定义LinkList */


10、单链表的读取:获取链表第i个数据元素的算法思路:
        1)声明一个结点p指向链表第一个结点,初始化j从1开始;
        2)当j<i时,就遍历链表,让p的指针向后移动,不断指向下一结点,j累加1;
        3)若到链表末尾p为空,则说明第i个元素不存在(链表为空或者当链表不为空时i大于链表长度);或j>i,说明第i个元素不存在(i小于1);
        4)否则查找成功,返回结点p的数据。
        实现算法代码如下:

/* 初始条件:链式线性表L已存在,1≤i≤链式线性表的长度 */
/* 操作结果:用e返回L中第i个数据元素的值 */
Status GetElem(LinkList L, int i, ElemType *e)
{
	int j;
	LinkList p;		      /* 声明一结点p */
	p = L->next;		  /* 让p指向链表L的第一个结点 */
	j = 1;		          /*  j为计数器 */
	while (p && j < i)    /* p不为空或者计数器j还没有等于i时,循环继续 */
	{   
		p = p->next;      /* 让p指向下一个结点 */
		++j;
	}
	if ( !p || j > i ) 
	{
		return ERROR;     /*  第i个元素不存在 */
	}	     
	*e = p->data;         /*  取第i个元素的数据 */
	return OK;
}


11、单链表的读取时间复杂度:此算法的时间复杂度取决于i的位置,当i=1时,不需要遍历,第一个就取出数据了,而当i=n时则遍历n-1次才可以。所以最坏情况的时间复杂度为O(n)。
12、单链表的插入:插入示意图如下:

    只需执行s->next=p->next;p->next=s;即可,但是这两句代码的执行次序可不能改变。 对于带有头节点的的单链表的表头和表尾插入的情况如下图:

单链表第i个数据插入节点的算法思路:
    1)声明一结点p指向链表头结点,初始化j从1开始;
    2)当j<i时,就遍历链表,让p的指针向后移动,不断指向下一结点,j累加1;
    3)若到链表末尾p为空,则说明第i个元素不存在(i 大于当前单链表长度+1,包括第i-1个元素也不存在);
    4)否则查找成功,在系统中生成一个空结点s;
    5)将数据元素e赋值给s->data;
    6)单链表的插入标准语句s->next=p->next;p->next=s;
    7)返回成功。
    实现算法代码如下:

/* 初始条件:链式线性表L已存在,1≤i≤链式线性表的长度+1*/
/* 操作结果:在L中第i个位置之前插入新的数据元素e*/
Status ListInsert(LinkList *L, int i, ElemType e)
{ 
	int j;
	LinkList p, s;
	p = *L;   
	j = 1;
	while (p && j < i)      /* 寻找第i个结点 */
	{
		p = p->next;
		++j;
	} 
	if (!p || j > i) 
	{
		return ERROR;       /* 第i个元素不存在 */
	}	       
	s = (LinkList)malloc(sizeof(struct Node));  /*  生成新结点(C语言标准函数) */
	s->data = e;  
	s->next = p->next;      /* 将p的后继结点赋值给s的后继  */
	p->next = s;            /* 将s赋值给p的后继 */
	return OK;
}


13、单链表的删除:删除示意图如下:

    删除q节点需要执行的操作就是p->next=p->next->next,即:q=p->next;p->next=q->next;
    单链表删除第i个数据结点的算法思路:
    1)声明一结点p指向链表头结点,初始化j从1开始;
    2)当j<i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1;
    3)若到链表末尾p->next为空,则说明第i个元素不存在;
    4)否则查找成功,将欲删除的结点p->next赋值给q;
    5)单链表的删除标准语句p->next=q-next;
    6)将q结点中的数据赋值给e;
    7)释放q结点;
    8)返回成功。
    实现算法代码如下:

/* 初始条件:链式线性表L已存在,1≤i≤链式线性表的长度 */
/* 操作结果:删除L的第i个数据元素,并用e返回其值*/
Status ListDelete(LinkList *L, int i, ElemType *e) 
{ 
	int j;
	LinkList p,q;
	p = *L;
	j = 1;
	while (p->next && j < i)	/* 遍历寻找第i个元素 */
	{
        p = p->next;
        ++j;
	}
	if (!(p->next) || j > i) 
	{
		return ERROR;           /* 第i个元素不存在 */
	}               
	q = p->next;
	p->next = q->next;			/* 将q的后继赋值给p的后继 */
	*e = q->data;               /* 将q结点中的数据给e */
	free(q);                    /* 让系统回收此结点,释放内存 */
	return OK;
}


14、单链表插入和删除的时间复杂度:都是由两部分组成,第一是遍历查找第i个元素,第二是插入或删除元素;它们的时间复杂度都是O(n)。若从第i个位置插入10个元素,对于顺序存储结构的线性表意味着每一次插入都需要移动n-i个元素,每次都是O(n),但是对于单链表而言只需要在第一次找到第i个位置的指针,仅此为O(n),接下来只是简单的通过赋值移动指针,时间复杂度都是O(1),所以对于插入和删除数据越频繁的操作,单链表的效率优势就越明显。
15、单链表的整表创建:对于单链表而言它所占用空间的大小和位置不像顺序线性表,是不需要预先分配划定的,所以创建单链表的过程就是一个动态生成链表的过程,其整表创建的算法思路如下:
      1)声明一结点p和计数器变量i;
      2)初始化一空链表L;
      3)让L的头结点的指针指向NULL,即建立一个带头结点的单链表;
      4)循环:生成一新结点赋值给p;随机生成一数字赋值给p的数据域p->data;将p插入到头结点与前一新结点之间;
      实现算法代码如下:

/*  随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */
void CreateListHead(LinkList *L, int n) 
{
	LinkList p;
	int i;
	srand(time(0));                                /* 初始化随机数种子 */
	*L = (LinkList)malloc(sizeof(struct Node));
	(*L)->next = NULL;                             /*  先建立一个带头结点的单链表 */
	for (i=0; i<n; i++) 
	{
		p = (LinkList)malloc(sizeof(struct Node)); /*  生成新结点 */
		p->data = rand()%100+1;                    /*  随机生成100以内的数字 */
		p->next = (*L)->next;    
		(*L)->next = p;						       /*  插入到表头 */
	}
}


这里始终是让新结点在第一的位置,可以把这种算法简称为头插法,其示意过程如下图:

每次都把新结点插在终端结点的后面称为尾插法,代码如下:

/*  随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法) */
void CreateListTail(LinkList *L, int n) 
{
	LinkList p,r;
	int i;
	srand(time(0));                                /* 初始化随机数种子 */
	*L = (LinkList)malloc(sizeof(struct Node));    /* L为整个线性表 */
	r = *L;                                        /* r为指向尾部的结点 */
	for (i = 0; i < n; i++) 
	{
		p = (LinkList)malloc(sizeof(struct Node)); /* 生成新结点 */
		p->data = rand()%100+1;                    /* 随机生成100以内的数字 */
		r->next = p;                               /* 将表尾终端结点的指针指向新结点 */
		r = p;                                     /* 将当前的新结点定义为表尾终端结点 */
	}
	r->next = NULL;                                /* 表示当前链表结束 */
}


16、单链表整表的删除:算法思路如下:
       1)声明一结点p和q;
       2)将第一个结点赋值给p;
       3)如果p不为空,将下一结点赋值给q;释放p;将q赋值给p;循环
       实现算法代码如下:

/* 初始条件:链式线性表L已存在。操作结果:将L重置为空表 */
Status ClearList(LinkList *L)
{ 
	LinkList p, q;
	p = (*L)->next;           /*  p指向第一个结点 */
	while(p)                  /*  没到表尾 */
	{
		q = p->next;
		free(p);
		p = q;
	}
	(*L)->next = NULL;        /* 头结点指针域为空 */
	return OK;
}


17、单链表结构与顺序存储结构优缺点:如下图

四、静态链表
1、用数组来代替指针来描述单链表,让数组的元素都是由两个数据域组成,data和cur,其中数据域data用来存放数据元素,数据域cur相当于单链表中的next指针,存放该元素的后继在数组中的下标,把这种用数组描述的链表叫做静态链表,这种描述方法还有起名叫游标实现法。
2、线性表的静态链表存储结构定义如下:

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 1000          /* 存储空间初始分配量 */

typedef int Status;           /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef char ElemType;        /* ElemType类型根据实际情况而定,这里假设为char */

/* 线性表的静态链表存储结构 */
struct Node 
{
    ElemType data;
    int cur;                  /* 游标(Cursor) ,为0时表示无指向 */
};
typedef struct Node StaticLinkList[MAXSIZE];


3、另外,对数组第一个和最后一个元素作为特殊元素处理,数据域不存数据。通常把未被使用的数组元素称为备用链表。而数组第一个元素的cur存放备用链表的第一个结点在数组中的下标;而数组的最后一个元素的cur则存放第一个有数值的元素的下标,相当于单链表中的头结点的作用,当整个链表为空时,则为0。如下图即为初始化的数组状态。

4、初始化数组,代码如下:

/* 将一维数组space中各分量链成一个备用链表,space[0].cur为头指针,"0"表示空指针 */
Status InitList(StaticLinkList space) 
{
	int i;
	for (i = 0; i < MAXSIZE-1; i++)  
	{
		space[i].cur = i+1;
	}	
	space[MAXSIZE-1].cur = 0; /* 目前静态链表为空,最后一个元素的cur为0 */
	return OK;
}


5、如果静态链表中已有数据了,其图示图下图。

6、静态链表要解决的问题:如何用静态模拟动态链表结构的存储空间的分配,需要时申请,无用时释放。在动态链表中,结点的申请和释放使用的是malloc()和free()函数来实现,而在静态链表中操作的是数组,不存在像动态链表的结点申请和释放问题,所以需要手动实现这两个函数。首先是申请,为了辨别数组中哪些分量未被使用,解决的办法是将所有未被使用过的以及已被删除的分量用游标链成一个备用的链表,每当进行插入时,便可以从备用链表上取得第一个结点作为待插入的新结点,实现代码如下:

/* 若备用空间链表非空,则返回分配的结点下标,否则返回0 */
int Malloc_SSL(StaticLinkList space) 
{ 
	int i = space[0].cur;           		/* 当前数组第一个元素的cur存的值 */
	                                		/* 就是要返回的第一个备用空闲的下标 */
	if (space[0]. cur)         
	    space[0]. cur = space[i].cur;       /* 由于要拿出一个分量来使用了, */
	                                        /* 所以我们就得把它的下一个 */
	                                        /* 分量用来做备用 */
	return i;
}

释放:

/*  将下标为k的空闲结点回收到备用链表 */
void Free_SSL(StaticLinkList space, int k) 
{  
    space[k].cur = space[0].cur;    /* 把第一个元素的cur值赋给要删除的分量cur */
    space[0].cur = k;               /* 把要删除的分量下标赋值给第一个元素的cur */
}


7、静态链表的插入操作:实现代码如下:
首先是求静态链表的数据元素个数函数:

/* 初始条件:静态链表L已存在。操作结果:返回L中数据元素个数 */
int ListLength(StaticLinkList L)
{
    int j = 0;
    int i = L[MAXSIZE-1].cur;
    while(i)
    {
        i = L[i].cur;
        j++;
    }
    return j;
}


然后是插入操作实现函数:

/*  在L中第i个元素之前插入新的数据元素e   */
Status ListInsert(StaticLinkList L, int i, ElemType e)   
{  
    int j, k, l;   
    k = MAXSIZE - 1;                     /* 注意k首先是最后一个元素的下标 */
    if (i < 1 || i > ListLength(L) + 1)   
    {
		return ERROR;
	}       
    j = Malloc_SSL(L);                   /* 获得空闲分量的下标 */
    if (j)   
    {   
		L[j].data = e;                   /* 将数据赋值给此分量的data */
		for(l = 1; l <= i - 1; l++)      /* 找到第i个元素之前的位置 */
		{
			k = L[k].cur;  
		}            
		L[j].cur = L[k].cur;             /* 把第i个元素之前的cur赋值给新元素的cur */
		L[k].cur = j;                    /* 把新元素的下标赋值给第i个元素之前元素的cur */
		return OK;   
    }   
    return ERROR;   
}


比如在上图的乙后面插入丙,结果如下图。

8、静态链表的删除操作:代码如下

/*  删除在L中第i个数据元素   */
Status ListDelete(StaticLinkList L, int i)   
{ 
    int j, k;   
    if (i < 1 || i > ListLength(L))   
    {
		return ERROR;
	}   
    k = MAXSIZE - 1;   
    for (j = 1; j <= i - 1; j++)   
    {
		k = L[k].cur; 
	}      
    j = L[k].cur;   
    L[k].cur = L[j].cur;   
    Free_SSL(L, j);   
    return OK;   
} 


比如继续在上图的结果中删除甲,结果如下:

9、静态链表的优缺点:总的来说,静态链表其实是为了给没有指针的高级语言设计的一种实现单链表能力的方法。其优缺点如下图。

五、循环链表
1、循环链表定义:将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表。
2、为了使空链表与非空链表处理一致,通常设一个头结点,但这头结点并不是必要的,循环链表带有头结点的空链表和非空链表如下图。

3、循环链表和单链表的主要差异在于循环的判断条件上,单链表是判断p->next是否为空,循环链表是判断p->next不等于头结点,则循环未结束。
4、在单链表中采用头结点时,可以用O(1)的时间访问第一个结点,用O(n)的时间访问到最后一个结点;采用指向终端结点的尾指针来表示循环链表时可以用O(1)的时间由链表指针访问到最后一个结点,如下图。

5、尾指针应用举例:将两个循环链表合并成一个表,要合并的两个循环链表如下图。

要合并它们只需要执行以下程序代码:

p=rearA->next;   /*保存A表的头结点*/
rearA->next=rearB->next->next;/*将本是指向B表的第一个结点(不是头结点)赋值给rearA->next*/
rearB->next=p; /*将原A表的头结点赋值给rearB->next*/
free(p);


示意图如下:

六、双向链表
1、双向链表定义:双向链表是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。
2、双向链表也可以是循环表,如下图是双向链表的循环带头结点的空链表和非空链表。

3、双向链表比单链表多了如可以反向遍历查找等操作,但是在插入和删除时,需要更改两个指针变量。对于插入操作重要的就是操作顺序很重要,如下图。

对于删除操作如下图。

4、双向链表由于保存了两份指针,所以在空间上要占用略多一些,但是对于结点的前后结点的操作带来了方便,可以有效提高算法的时间性能,也就是用空间来换时间。

顺序线性表——课上练 2)此处假设线性表中的元素用于表示集合,不考虑线性表中元素的位置,移除线性表中的所有重复元素;不要使用额外的数组空间,必须在原地修改输入数组并在使用O(1)额外空间的条件下完成。在顺序线性表中下标为p位置、p位置之前、p位置之后插入数据元素。本关要求按照完成顺序表数据类型定义,并初始化一个顺序线性表。本关任务销毁线性表的实质时实现动态分配的线性表空间回收。(1)使用将顺序表L中值为x的数据元素替换为y;(2)在顺序表L中删除与参数x值相同的数据元素。(1)在顺序表L中删除下标pos处的数据元素。... 阅读详情

相关推荐

S32K344 Bootloader实战:一个按键实现从Boot到App的无缝跳转(附完整代码)

本文详细介绍了基于NXP S32K344微控制器的Bootloader开发实战,重点解析如何通过一个硬件按键实现从Boot到App的可靠跳转。内容涵盖内存分区规划、中断向量表重映射、外设初始状态管理等核心要素,并提供了完整的代码示例和调试技巧,适用于汽车电子和工业控制等高可靠性应用场景。

weixin_29192365的博客 307

7-1 数据结构实验五 快速排序

用顺序表作存储结构,输入一组数据,用快速排序法对其进行排序。

wzy992981933的博客 2207

vcs覆盖率相关

选择要查看的覆盖率点,右键选择 show xxx tests;

qq_40571921的博客 2390

6-7 数据结构考题 - 快速排序 - 划分函数

6-7 数据结构考题 - 快速排序 - 划分函数 (25 分) 用顺序表作存储结构,输入一组数据,用快速排序法对其进行排序。 顺序表的类型描述: #define MAXSIZE 50 // MAXSIZE为最大数据元素数目 typedef int ElemType; typedef struct { ElemType r[MAXSIZE +1]; // r[0]闲置或另作它用 int length; }SqList; 函数接口定义: 下面给出了 快速排序 - 划分函数 的大部分

国家一级致癌物 2124

【CADARXC++】ObjectArx2023 C++ CAD二次开发环境配置笔记

从官网或第三方平台下载以下AUtoCAD2023、VisualStudio2019和ObjectArx2023安装时请注意安装顺序。

BIMCATIA的博客 1789

8155平台multi-display(多屏显示)原理与配置

8155平台多屏互动原理与配置

漂流瓶の海岸 1606

C 线性表的顺序存储实现及插入、删除等操作示例

一、线性表的定义 线性表(Linear List)是由同一类型元素构成的有序序列的线性结构。线性表中元素的个数称为线性表的长度;线性表内没有元素(长度为0)时,称为空表;表的起始位置称为表头,表的结束位置称为表尾。 线性表的抽象数据类型描述为: 类型名称:线性表(List) 数据对象集:线性表是由n个元素构成的有序序列(a1到an),其中a1是表的第一个元素(表头),an是表的最后一个元素...

weixin_30486037的博客 918

LMI线性矩阵不等式之非线性变量处理

​ 如果一个LMI线性矩阵不等式中的某项存在两个矩阵变量相乘,那么称该类情形为非线性矩阵不等式,而要直接求解时很困难的,而且LMI工具箱也无法求解非线性矩阵,所以需要通过变量替换法进行处理。 ​...

Mr.邹的博客 4550

大话数据结构——第三章线性表读书笔记

tkzky001的博客 258

[语义分割]SPP、空洞卷积与ASPP总结

ASPP全称:Atrous Spatial Pyramid Pooling,中文可以理解为空洞空间卷积池化金字塔或者多孔空间金字塔池化。在这其中,要理解两个概念:一个是SPP,池化金字塔结构或者叫空间金字塔池化层,都是一个东西;另一个是Atrous,空洞卷积,两个加在一起就是ASPP。 首先说一下SPP:Spatial Pyramid Pooling。这个结构出自于论文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Re

lipengfei0427的博客 2万+

新手必读!2025最全AI智能体入门手册,50个问题全讲透

感知(Perception):能读取环境,比如读取网页数据、识别用户输入、接入 API;思考(Reasoning/Planning):理解任务目标,规划出行动步骤;行动(Action):调工具、查资料、发消息、写入数据库……直接执行任务。有了这三步,智能体才不是“一个会说话的大模型”,而是真正的“能落地执行的工作代理人”。多个 Agent 分工协作,每个智能体负责一个角色或任务节点,像一个“虚拟团队”。一个爬数据的 Agent,一个提炼要点的 Agent,一个撰写报告的 Agent,

互联网架构师笔记 1968

第三章 线性表《大话数据结构》读后笔记

第三章 线性表《大话数据结构》读后笔记 第二章《大话数据结构》读后笔记 文章目录第三章 线性表《大话数据结构》读后笔记线性表的定义线性表顺序存储结构线性表链式存储结构单链表结构与顺序存储结构优缺点静态链表循环链表双向链表 线性表的定义 零个或多个数据元素的有限序列 线性表顺序存储结构 即数组存储,顺序存储结构需要在内存中划出地址连续的空间。 当要get某个元素时:只需要通过下标拿即可时间复杂度O(1) 当往中间插入某个元素时:所有后面都要往后移动 最坏时间复杂度O(n),最好O(1), 平均时间复杂

zhengshaopeng_1的博客 405

openharmony之UniProton内核技术揭秘:鸿蒙面向工业控制领域的RTOS设计之道

UniProton是鸿蒙操作系统面向工业控制领域的轻量级实时操作系统(RTOS),专为资源受限的嵌入式设备设计。作为鸿蒙生态的重要组成部分,UniProton提供了高效的实时任务调度、内存管理和IPC机制,满足工业控制场景对实时性和可靠性的严格要求。想象一下,UniProton就像一个超级聪明的管家,管理着电子设备里所有的工作。让你的智能手表既能显示时间,又能接收消息让家里的扫地机器人既能避开障碍物,又能记住哪里已经打扫过了让工厂里的机器人手臂既能精确地抓取东西,又能快速地完成任务实时性强。

m0_67505153的博客 883

《大话数据结构》第三章线性表学习笔记

《大话数据结构》第三章线性表学习笔记 线性表顺序存储 线性表的顺序插入: 1、如果线性表长度大于数组长度,则抛出异常; 2、如果插入位置不合理,抛出异常; 3、从最后一个元素开始向前遍历到第 i 个位置,分别将他们向后移动一个位置; 4、将要插入元素填入位置 i 处; 5、表长加1。 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */ /* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */ Status ListInsert(SqList *L,int i,E

weixin_45632393的博客 232

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

大话数据结构笔记——第三章:线性表

线性表线性表的定义线性表的抽象数据类型线性表的顺序存储结构顺序存储结构的插入与删除获取元素操作插入操作 线性表的定义 线性表(List):零个或多个数据元素的有限序列,直接前驱元素,直接后继元素。在线性表中间的数据元素,有且只有一个直接前驱元素和直接后继元素。线性表元素的个数n(n>=0)定义为线性表的长度,当n=0时称为空表。在较复杂的线性表中,一个数据元素可以由若干个数据项组成。 线性表...

weixin_43155076的博客 839

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

大话数据结构学习笔记-第三章线性表

目录:一.大话数据结构电子图书下载地址二.线性表三.顺序存储结构1.什么是顺序存储结构?2.顺序存储结构索引表常用操作代码(1) 存和插入操作(增)(2) 删除操作(删)(3) 修改元素操作(改)(4) 获取元素操作(查)3.线性表顺序存储结构的优缺点四.链式存储结构 一.大话数据结构电子图书下载地址 大话数据结构下载链接 百度网盘密码:i70v 二.线性表 什么是线性表? 书上的定义:零个或多个数据元素的有限序列。 星座列表是否为一个线性表:是的 某家公司的组织架构是否为线性表:不是的 本章节框

孤夜的博客 1315

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【java笔记】大话数据结构第三章 —线性表

一 线性表定义:零个或多个元素的有限序列。 ① 首先它是一个序列,也就是说元素之间是有顺序的,如存在多个元素,则第一个元素无前驱,最后一个元 素没有后继。其他元素有且只有一个前驱和一个后继。 ② 线性表强调是有限的,也就是说线性表数据是有限的。 二 线性表抽象数据类型描述 所以线性表的抽像数据类型定义如下 public interface IList { /* ADT 线性...

tunmengsmile的博客 383

读书笔记:《大话数据结构》第三章线性表

1.线性表的定义 定义:线性表(List)是零个或者多个数据元素的有限序列。 关键点: 序列意味着元素之间是有顺序的。 线性表是有限的。 在复杂的线性表中,一个数据元素可以由若干个数据项组成。 线性表中数据类型要相同。 2.线性表的抽象数据模型 3…线性表的顺序存储结构 1.定义:线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。 存储方式:用一维数组来实现顺序存...

weixin_43305951的博客 253

《大话数据结构》第三章:线性表(笔记)

第三章:线性表 线性表(List):零个或多个元素的有限序列。 线性表的基本操作:获取长度、读取元素、插入元素、删除元素 线性边的存储结构: 顺序存储结构:用一段连续的存储单元依次存储线性表的数据元素。 时间复杂度: 存、取数据时:O(1) 删除、插入数据:O(n) 特点:无需为表示元素间逻辑关系为额外的增加存储空间,可快速存取任意位置元素,但插入和删除操作需要移动大量元素,当线性表长度变化较大时,难以确定存储空间的容量,可能会造成存储空间碎片。 线性表的链式存储结构: 链式存储:用一组任意的存储单元存

weixin_42367960的博客 200

《大话数据结构》第三章学习笔记--线性表(一)

线性表的定义 线性表:零个或多个数据元素的有限序列。 线性表元素的个数n定义为线性表的长度。n为0时,为空表。 在比较复杂的线性表中,一个数据元素可以由若干个数据项组成。 线性表的存储结构 顺序存储结构 可以用C语言中的一维数组来实现,每个数据元素的类型都相同。 描述顺序结构存储结构需要三个属性: 1.存储空间的起始位置:数组date,它的存储位置就是存储空间的存储位置。。 2.线性表的最大存储容量:数组长度maxsize。 3.线性表的当前长度:length 数据长度和线性表长度

MogulNemenis的博客 518

《大话数据结构》笔记 第三章----线性表的顺序存储结构

零个或多个数据元素的有限序列。

nakedkai的博客 92

读书笔记-《大话数据结构》第三章 线性表之顺序存储结构

3.2线性表:零个或多个数据元素的有限序列    线性表元素的个数n(n>=0)定义为线性表的长度,当n=0时成为空表。

小鱼酱的博客 761

读书笔记-《大话数据结构》第三章 线性表之链式存储结构

线性表之链式存储结构 线性表的顺序存储结构要求逻辑关系上相邻的元素在物理位置上也相邻,这样方便了随机存取,但是在插入和删除元素时,需要移动大量元素,而线性表的链式存储则不要求逻辑上相邻的元素在物理位置上也相邻,因此它没有顺序存储结构的可随机存取的优点,不过在插入和删除元素时比较方便。 1.单链表 一.单链表可由头指针唯一确定,在C语言中可用“结构指针”来描述: 1: type

小鱼酱的博客 1035
上一篇: 《大话数据结构》笔记之 第二章 算法
下一篇: 《大话数据结构》笔记之 第四章 栈与队列
漂流在深圳
博客等级 码龄15年 30粉丝 60原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值