线性表:零个或多个数据元素的有限序列。
注意:
1线性表有序
元素之间有序列。若元素存在多个,则第一个无前驱,最后一个无后驱,其他元素仅有一个前驱和后驱。
2.线性表有限
数列之内的数据有限。无限的数列只存在于数学概念之中。
所以线性表元素个数n就定义为线性表的长度,当n=0时,为空表。
线性表的两种物理结构:
一.顺序存储结构:
1.定义
用一段地址连续的存储单元依次存储线性表的数据结构。
数组的长度是线性表的存储空间的长度,存储分配后这个量一般是不变的。
我更愿意直呼它为数组。
2.插入
如果我们有一个长度为len的数组,要在它的第i个位置插入新元素e,如何操作呢?
#include
int len;//数组长度
int maxsize;
int List[maxsize];
int Listinsert(int i,int e)
{
int j;
if(i>maxsize)//顺序线性表已满
return 0;
if(i<=len&&i>=0)
{
for(j=len-1;j>=i-1;j--)//i位置以后的元素向后移一位
{
List[j+1]=List[j];
}
}
List[i-1]=e;
len++;
return 1;
}
在确保线性表空间未满的情况下,将第i-1到len-1的所有元素全部向后移一位,再将e赋值给List[i-1]。
3.删除
同上,若是想删除线性表中i位置的元素,又应该怎操作呢。
#include
int len;//数组长度
int maxsize;
int List[maxsize];
int Listinsert(int i)
{
int j;
if(i>maxsize)
return 0;
if(i<len)//删除位置不在线性表最后
{
for(j=i;j<len;j++)//i位置以后的元素向前移一位
{
List[j-1]=List[j];
}
}
len--;
return 1;
}
二.链式存储结构
1.链式存储结构就是利用结构体,构造一个数据域和一个指针域。数据域存数据,指针域存指向下一个数据域的指针,这样层层联系,构建出一个链表,链表的存储没有特定的位置,而是通过指针域将每个数据域链接,并且可以一边存一边开辟空间,不会造成空间的浪费也更方便插入和删除操作。
链表尾节点通常指向NULL。
创建结点
struct lianbiao
{
int num1;
struct lianbiao *next;
};
*next即为指向下一个节点的指针域。
2.链表的创建
int m=0,n;
scanf("%d",&n);//n为链表长度
m=n;
struct lianbiao *head,*p3,*p4;
head=(struct lianbiao *)malloc(sizeof(struct lianbiao));//开辟空间
p3=(struct lianbiao *)malloc(sizeof(struct lianbiao));
p4=head;
scanf("%d",&(p3->num1));
while(n!=1)
{
p3->next=NULL;
p4->next=p3;
p4=p3;
p3=(struct lianbiao *)malloc(sizeof(struct lianbiao));
int x;
scanf("%d",&x);
p3->num1=x;
n--;
}
p3->next=NULL;
3.链表插入
在节点p后插入节点s:
将p的后继节点改成s的后继节点,再把节点s变成p的后继节点。
代码如下:
s->next=p->next;
p->next=s;
4.链表删除
删除节点p后的节点q:
将p的后继节点改为p的后继节点的后继节点。
代码如下:
q=p->next;
p->next=q->next;
5.静态链表
除动态链表以外,还有静态链表。
静态链表是用数组描述的。通过结构体我们可以将数组中的元素都由两个数据域构成,一个是存放数据元素的data,另一个cur则相当于动态链表的next指针,我们称之为游标,用来存放该元素的后继在数组中的下标。
这样,要插入的时候只需要将数据存入数组末尾的空间,并更改游标值即可。这里不做详细解说 懒
6.循环链表
将单链表的终端节点的指针指向头节点,就使整个单链表形成一个环,这种头尾相接的单链表成为单循环链表,简称循环链表。