**
**
有序、有限、最多一个前驱和一个后继
基本操作:
InitList(&L)
ListEmpty(L)
ClearList(&L)
GetElem(L, i, &e)
LocateElem(L, e)
ListInsert(&L, i, e)
ListDelete(&L, i, &e)
ListLength(L)
线性表集合A和B的合并操作
/*将所有的在线性表Lb中,但不在La中的数据元素插入到La中*/
void union(List *La, List Lb)
{
int La_len, Lb_len;
ElemType e;
La_len = ListLength(La);
Lb_len = ListLength(Lb);
for(int i=1; i<=Lb_len; i++){
GetElem(Lb,i,&e);
if(!LocateElem(La,e))
ListInsert(&La,++La_len,e);
}
}
线性表的顺序存储的结构代码
#define MaxSize 20
typedef int ElemType
typedef struct{
Elemtype data[MaxSize];
int Length;
}SqList;
随机存取结构,其存取时间性能为O(1)
获得元素的操作
#define OK 1
#define ERROR 0
#define TRUE 1
#define FASLE 0
typedef int Status;
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;
}
插入操作
Statue ListInsert(SqList *L, int i, ElemType e){
int k;
if(L->Length == MaxSize)
return ERROR;
if(i<1 || i>L->Length+1)
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;
}
删除操作
Statue 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-1; k<L->Length-1; k++)
L->data[k]=L->data[k+1]
}
L->Length--;
return OK;
}
存取快,插入删除慢
链式存储结构
头指针是必要元素,头指针均不为空,但头结点不一定是链表的必要元素,头结点是为了操作的统一和方便设立的,放在第一元素节点前,数据域一般放链表长度
若线性表为空表,则头结点的指针域为空。
单链表的结构代码
typedef struct Node{
//结点由数据域和指针域组成
ElemType data;
struct Node *next;
} Node, *LinkList;
单链表的读取
Status GetElem(LinkList L, int i, ElemType *e){
//LinkList即为Node*
int j;
LinkList p;
p=L->next; //让p指向第一个结点,L理解为头结点的指针
j=1; //j为计数器
while(p && j<i) //p不为空且计数器j还没等于i时,循环继续
{
p=p->next;
j++;
}
if(!p || j>i)
return ERROR;
*e=p->data;
return OK;
}
单链表的插入
Status LinkInsert(LinkList *L, int i, ElemType e){
int j;
LinkList p, s;
p=*L;
j=0;
while(!p && j1){
p=p->next;
++j;
}
if(!p || j>i-1)
return ERROR;
s=(LinkList)malloc(sizeof(Node));
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
单链表的删除
Status ListDelete(LinkList *L, int i, ElemType *e){
int j;
LinkList p, q;
p=*L;
j=0;
while(p && j1){
p=p->next;
++j;
}
if(!p || j>i-1)
return ERROR;
if(!(p->next))
return ERROR;
q=p->next;
p->next = q->next;
*e = q->data;
free(q);
return OK
}
创建单链表 头插法
void CreateListHead(LinkList *L, int n){
LinkList p;
int i;
srand(time(0));
*L =(LinkList)malloc(sizeof(Node));
(*L)->next=NULL;
for(int i=1; i<=n; i++){
p=(LinkList)malloc(sizeof(Node));
p->data = rand()%100+1;
p->next = (*L)->next;
(*L)->next = p;
}
}
创建单链表 尾插法
void CreateLinkTail(LinkList *L, int n){
LinkList p, r;
int i;
srand(time(0));
(*L)=(LinkList)malloc(sizeof(Node));
r=*L;
for(i=1; i<=n; i++){
p = (LinkList)malloc(sizeof(Node));
p->data = rand()%100+1;
r->next = p;
//p->next = r->next;
r=p;
}
r->next=NULL;
}
单链表的整表删除
Status ClearList(LinkList *L)
{
LinkList p,q;
p=(*L)->next;
while(p){
q=p->next;
free(p);
p=q;
}
(*L)->next=NULL;
return OK;
}
#define MaxSize 1000
typedef struct{
ElemType data;
int cur; //游标cursor
}Component, StaticLinkList[MaxSize];
初始化
Statues InitList(StaticLinkList space){
int i;
for(i=0; i1; i++)
space[i].cur = i+1;
space[i].cur = 0;
return OK;
}
/*数组第一个元素的cur用来存放备用链表第一个节点的下标
把未被使用的数组元素成为备用链表,
下一位置数据为空则next用0表示
数组的最后一个元素的cur用来存放第一个插入元素的下标,当整个链表为空时,为0*/
链表的插入操作
int Malloc_SLL(StaticLinkList space){
int i=space[0].cur;
if(space[0].cur)
space[0].cur = space[i].cur;
return i;
}
Status ListInsert(SaticLinkList L, int i, ElemType e){
int j, k, l;
k = MaxSize-1;
j = Malloc_SLL(L);
if(i<1 || i>ListLength(L)+1)
return ERROR;
if(j){
L[j].data = e;
for(l=1; l<=i-1; l++)
k=L[k].cur;
L[j].cur=L[k].cur;
L[k].cur=j;
return OK;
}
return ERROR;
}
int ListLength(StaticLinkList space){
int j=0;
int i=space[MaxSize-1].cur;
while(i){
j++;
i=space[i].cur;
}
return j;
}
链表的删除操作
Status ListDelete(StaticLinkList L, int i){
int j, k;
k=MaxSize-1;
if(i<1 || i>ListLength(L))
return ERROR;
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;
}
void Free_SSL(StaticLinkList space, int k){
space[k].cur=space[0].cur;
space[0].cur=k;
}
int ListLength(StaticLinkList L){
int j,k,i;
i=L[Maxsize-1].cur;
j=0;
while(i){
++j;
i=L[i].cur;
}
return j;
}
循环链表
设置循环链表的尾指针rear,便于访问尾结点
判断循环结束的条件 p->next 是否等于头结点
p=rearA->next;
rearA->next=rearB->next->next;
rearB->next=p;
free(p);
typedef struct DulNode
{
ElemType data;
struct DulNode *prior;
struct DulNode *next;
} DulNode, *DuLinkList;
双向链表的插入s操作
s->prior=p;
s->next=p->next;
p->next=s;
p->next->prior=s;
Status DuListInsert(DuLinkList *L, int i, ElemType e){
int j;
DuLinkList p,s;
p=*L;
j=0;
while(p->next && j<i){
++j;
p=p->next;
}
if(!p || j>i)
return ERROR;
s=(DuLinkList)malloc(sizeof(DulNode));
s->data=e;
s->next=p;
s->prior=p->prior;
p->prior=s;
s->prior->next=s;
return OK;
}
双向链表的删除p操作
p->next->prior = p->prior;
p->prior->next = p->next;
free(p);
Status DuListDelete(DuLinkList *L, int i, ElemType *e){
int j;
DuLinkList p;
p=*L;
j=0;
while(p->next && j<i){
p=p->next;
++j;
}
if(!p || j>i)
return ERROR;
*e=p->data;
p->next->prior = p->prior;
p->prior->next = p->next;
free(p);
return OK;
}