单链表
1.头插法
typedef struct LNode{
ElemType data;//数据域
struct LNode *next; //指针域
}LNode,*LinkList;
LinkList CreateList1(LinkList &L){
LNode *s;
int x;
L->next=null;//初始为空链表
scanf("%d",&x);
while(x!=9999)//输入9999表示结束
{
s=(LNode*)malloc(sizeof(LNode));//创建新结点
s-data=x;
s->next=L->next;
L->next=s;//新结点插入到链表中,L为头指针
scanf("%d",&x);
}
}
2.尾插法
LinkList CreateList2(LinkList &L){
L=(LinkList)malloc(sizeof(LNode));
LNode *s,*r=L;//r为表尾指针
int x;
scanf("%d",&x);
while(x!=9999)//输入9999表示结束
{
s=(LNode*)malloc(sizeof(LNode));//创建新结点
s-data=x;
r->next=s->next;
r=s;//r指向新的表尾结点
scanf("%d",&x);
}
r->next=null;//尾结点置空
return L;
}
3.按序号查找结点
LNode *GetElemt(LinkList L,int i){
//该算法取出链表中i位置的结点指针
int j=1;
LNode *p=L->next;
if(i==0)
return L;
if(i<1)
return null;
while(p&&j<i){
p=p->next;
j++;
}
return p;//如果i大于表长,p=null
}
时间复杂度O(n)
4.按值查找结点
LNode *LocateElemt(LinkList L,ElemType e){
//该算法取出链表中值为e的结点指针
LNode *p=L->next;
while(p!=NULL&&p->data!=e){
p=p->next;
}
return p;
}
时间复杂度O(n)
5.插入结点
- 前插操作
给定第i-1个结点,将新的结点插入到后面成为第i个结点
p=GetElemt(L,i-1)//获得i的前驱结点
s->next=p->next;
p->next=s;
【注】顺序不可改变
- 后插操作
给定第i个结点,插入新的结点到第i个结点的前面成为新的第i个位置
若使用前插法,时间复杂度为O(n);
s->next=p->next;
p->next=s;
temp=p->data; //交换s,p的数据部分
p->data=s->data;
s->data=temp;
6.删除结点
- 获取要删除结点的前驱结点
p=GetElemt(L,i-1)//获得i的前驱结点
q=p->next;//q指向被删除结点
p->next=q->next;
free(q);//释放q 结点
- 删除要删除结点的后继结点,交换数据即可
q=p->next;
p->data=p->next->data;
p->next=q->next;
free(q);
7.求表长
表长不包括头结点
双链表
typedef struct DNode{
ElemType data;//数据域
struct DNode *next,*prior;//前驱和后继结点
}DNode,*DLinkList;
插入结点
s->next = p->next;//1
p->next->prior=s;//2
p->next=s;//3
s->prior=p;//4
【注】1,2两步必须在3之前
删除结点
//删除q结点
p->next=q->next;
q->next->proir=p;
free(q);
循环单链表
表尾插入与单链表有所不同,设立尾指针效率更高
表空的条件:L->next==L
循环双链表
p是尾指针,则p->next==L;L->prior==p;
表空的条件:L->prior==L->next==L
静态链表
#define MaxSize 50
typedef struct{
ElemType data;
int next;
}SLinkList[MaxSize];
结束标志:next==-1;