单链表:从一个结点出发,只能找到后续的各个节点
循环单链表:从一个结点出发,可以找到其他任何一个结点
双链表:表头结点的prior指向NULL,表尾结点的next指向NULL
循环双链表:表头结点的prior指向表尾节点,表尾节点的next指向头节点
尾插法建立单链表
LinkList List_Tailnsert(LinkList &L) //正向建立单链表
{
int x; //设ElemTtpe为整型
L=(LinkList)malloc(sizeof(LNode)); //建立头结点,初始化空表
LNode *s,*r=L; //r为表尾指针
scanf("%d",&x);//输入结点的值
while(X!=9999) //输入9999表示结束(注意:9999只是一个特殊值)
{
s=(LNode *)malloc(sizeof(LNode));
s->data=x; //在r结点之后插入元素x
r->date=s;
r=s; //r指向新的表尾节点(永远保持r指向最后一个结点)
scanf("%d",&x);
}
r->next=NULL; //尾结点指针置空
return L;
}
时间复杂度为O(n)
LinkList和LNode *是一个东西,区别在于LinkList指的是单链表,LNode *指节点
头插法建立单链表,链表的逆置是它的一个重要的应用
LinkList List_HeadInsert(LinkList &L) //逆向建立单链表
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode)); //创建头结点
L->next=NULL; //初始化为空链表(只要是初始化链表,都先把头指针指向NULL)
scanf("%d",&x); //输入结点的值
while(x!=9999)
{
s=(LNode *)malloc(sizeof(LNode)); //创建新结点
s->data=x;
s->next=L->next;
L->next=s; //将新结点插入表中,L为头指针
scanf("%d",&x);
}
return L;
}
双链表的插入
bool InsertNextDNode(DNode *p,DNode *s) //在p结点之后插入s结点 (bool类型表示是否插入成功)
{
if(p==NULL||s==NULL) //非法参数
return false;
s->next=p->next;
if(p->next!=NULL) //如果p结点有后继结点
p->next->prior=s;
s->prior=p;
p->next=s;
return true;
}
双链表的删除
bool DeleteNextDNode(DNode *p)
{
if(p==NULL)
return false;
DNode *p=p->next; //找到p的后继结点q
if(q==NULL) return false //p没有后继
p->next=q->next;
if(q->next!=NULL) //q结点不是最后一个结点
q->next->prior=p;
free(p); //释放结点空间
return ture;
}
void DestroyList(DLink &L) //循环释放各个数据结点
{
while(L->next!=NULL)
DeleteNextDNode(L);
free(p); //释放头结点
L=NULL; //头指针指向NULL;
}
双链表不可随机存取,按位查找,按值查找操作都只能用遍历的方式进行实现,时间复杂度为O(n)
循环单链表
typedef struct LNode //定义单链表结点类型
{
ElemType data; //每个节点存放一个数据元素
struct LNode *next; //指针指向下一个结点
}LNode,*LinkList;
//初始化一个循环单链表
bool InitList(LinkList &L)
{
L=(LNode *)malloc(sizeof(LNode));//分配一个头节点
if(L==NULL) //内存不足,分配失败
return false;
L->next=L; //头节点next指向头节点
return true;
}
//判断循环单链表是否为空
bool Empty(LinkList L)
{
if(L->next==L)
return true;
else
return false;
}
//判断节点p是否为循环单链表的表尾节点
bool isTail(LinkList L,LNode *p)
{
if (p->next==L)
return true;
else
return false;
}
循环双链表的插入
bool InsertNextDNode(DNode *p,DNode *s)
{
s->next=p->next; //将结点*s插入到结点*p之后
p->next->prior=s;
s->prior=p;
p->next=s;
}