说明:本笔记依照《王道论坛-数据结构》视频内容整理。 单链表:无法逆向检索,有时候不太方方便。
双链表:可进可退,存储密度更低一点。
一、双链表结点
typedef int ElemType;
typedef struct lNode{
ElemType data;
struct lNode *prior,*next;
}lNode, *linkList;
二、操作
int initList(linkList *l);
int destroyList(linkList *l);
int listInsert(linkList *l,int i,ElemType e);
int listDelete(linkList *l,int i,ElemType *e);
lNode* locateElem(linkList l,ElemType e);
lNode* getElem(linkList l,int i);
int printfList(linkList l);
int insertNextNode(lNode *p,lNode *s);
int insertPriorNode(lNode *p,lNode *s);
int tailInsert(linkList l,ElemType e);
int headInsert(linkList l,ElemType e);
1、InitList(&L)
双链表初始化。
int initList(linkList *l)
{
*l = (lNode*)malloc(sizeof(lNode));
if(*l == NULL) return 1;
(*l)->prior = NULL;
(*l)->next = NULL;
(*l)->data = 0;
return 0;
}
2、DestroyList(&L)
双链表销毁。
int destroyList(linkList *l)
{
lNode *d = *l;
while(d != NULL){
(*l) = d->next;
printf("d->data = %d\n",d->data);
free(d);
d = *l;
}
return 0;
}
3、ListInsert(&L,i,e)
按位序插入。在表 L 中的第 i 个位置插入指定元素 e。
设计思路:找到第 i-1 个节点,将新节点插入其后。
int listInsert(linkList *l,int i,ElemType e)
{
if(i<1) return 1;
lNode *p = NULL;
int j = 0;
p = *l;
while(p!=NULL && j<i-1){
p = p->next;
j++;
}
if (p == NULL) return 1;
lNode *s = (lNode*)malloc(sizeof(lNode));
s->data = e;
s->next = p->next;
if(p->next != NULL) p->next->prior = s;
s->prior = p;
p->next = s;
return 0;
}
4、ListDelete(&L,i,&e)
按位序删除。删除表 L 中第 i 个位置的元素,并用 e 返回删除元素的值。
设计思路:找到第 i-1 个节点,释放第 i 个结点。
int listDelete(linkList *l,int i,ElemType *e)
{
if(i < 1) return 1;
lNode *p = NULL;
int j = 0;
p = *l;
while(p!=NULL && j<i-1){
p = p->next;
j++;
}
if(p == NULL) return 1;
if(p->next == NULL) return 1;
lNode *s = p->next;
(*e) = p->data;
p->next = s->next;
if(s->next!=NULL) s->next->prior = p;
free(s);
return 0;
}
5、LocateElem(L,e)
按值查找操作。在表 L 中查找具有给定关键字值的元素。
lNode* locateElem(linkList l,ElemType e)
{
lNode *p = l->next;
while(p!=NULL && p->data!=e){
p=p->next;
}
return p;
}
6、GetElem(L,i)
按位查找。返回第 i 个元素。
lNode* getElem(linkList l,int i)
{
if(i<0) return NULL;
lNode *p = NULL;
int j = 0;
p = l;
while(p!=NULL && j<i){
p=p->next;
j++;
}
return p;
}
7、Length(L)
获取链表长度。
未实现。
8、PrintfList(L)
打印链表内容。
int printfList(linkList l)
{
lNode *p = l;
while(p != NULL){
printf("p->data = %d\n",p->data);
p = p->next;
}
return 0;
}
9、InsertNextNode(p,s)
int insertNextNode(lNode *p,lNode *s)
{
if(p==NULL || s==NULL) return 1;
s->next = p->next;
if(p->next!=NULL) p->next->prior=s;
s->prior=p;
p->next=s;
return 0;
}
10、InsertPriorNode(p,s)
按结点前插。在 p 结点之前查找结点 s。
int insertPriorNode(lNode *p,lNode *s)
{
if(p==NULL || s==NULL) return 1;
s->prior=p->prior;
if(p->prior!=NULL) p->prior->next=s;
s->next=p;
p->prior=s;
return 0;
}
11、tailInsert(l,e)
链表后插操作。主要用于单链表创建。
链表后插操作单链表建立流程:
1、初始化一个单链表。
2、每次取一个数据插入到表尾。
int tailInsert(linkList l,ElemType e)
{
lNode *s = l;
while(s->next!=NULL){
s = s->next;
}
lNode *p = (lNode*)malloc(sizeof(lNode));
p->data = e;
return insertNextNode(s,p);
}
12、headInsert(l,e)
链表头插操作。主要用于单链表创建。
链表头插操作单链表建立流程:
1、初始化一个单链表。
2、每次取一个数据插入到表头。
int headInsert(linkList l,ElemType e)
{
lNode *p = (lNode*)malloc(sizeof(lNode));
p->data = e;
return insertNextNode(l,p);
}
三、总结
1、在更改链表时代码有所区别,单链表操作一个指针,双链表操作两个指针。
2、不涉及链表更改,操作相同
|