文章目录
1、双链表的结构
从图结构可以看出,双链表具有一个指向前驱结点的指针和一个指向后继结点的指针,所以,双链表中,结点是这样定义的:
typedef int Elem;
typedef struct DualNode {
Elem elem;
struct DualNode *prev; //前驱结点
struct DualNode *next; //后继结点
} DualNode;
typedef struct {
DualNode dummy;
int length;
}List;
一个含有假结点的完整循环双链表:
空表:
2、创建一个新结点
生成一个新的结点,结点的值通过参数传入:
DualNode *nodeNew(Elem elem) //生成一个结点
{
DaulNode *node = malloc(sizeof(DaulNode));
node -> next = NULL:
node -> prev = NULL;
node -> elem = elem;
return node;
}
释放结点:
void nodeDelete(DaulNode *node)
{
free(node);
}
3 、插入结点
有一个新的结点s,要插入到p结点的前面,一定要按照下面几步顺序来完成:
void nodeLink(DaulNode *prev,DaulNode *s,DaulNode *next)
{
s -> next = next;
s -> prev = p ->prev;
prev -> next = s;
next -> prev = s;
}
第四部不可提前执行;
4、删除结点
删除结点更为简单:
void nodeUnlink(Daulnode *p)
{
p -> prev ->next = p ->next;
p -> next -> prev= p -> prior;
free(p);
}
5、创建双链表
void listInit(List *list)
{
DaulNode *dummy = &list -> dummy;
dummy -> next = dummy;
dummy -> prev = dummy;
dummy -> length = 0;
}
dummy是一个假结点,也就是头结点,他的数据段用来存放链表的长度;
6、销毁双链表
销毁结点实则是把链表转化为空表的一个过程,通过一 一删除假结点的后继(头结点)来完成链表的销毁:
void listDestroy(List *list)
{
DaulNode *dummy = &list -> dummy;
while(dummy -> next != dummy)
{
DaulNode *node = dummy -> next;
nodeUnlink(node);
nodeDelete(node);
list -> length--;
}
}
7、获取头结点结点和尾结点
头结点是指第一个真实结点,而假结点指向头结点
DaulNode *GetHeadNode(List *list)
{
asser(list -> length > 0);
return list -> dummy.next;
}
DaulNode *GetTailNode(List *list)
{
asser(list -> length > 0);
return list -> dummy.prev;
}
8、链表长度
假结点还有一个成员length
int listLength(List *list)
{
return list -> length;
}
判断链表是空同样用length即可;
9、获取指定位置的结点
DaulNode *GetNode(List *list,int index)
{
assert(index >= 0 && index <= list -> length);
int i;
DaulNode *node;
node = list -> dummy.next; //指向链表的头结点
for(i = 0; i < index; i++)
node = node -> next;
assert(i == index);
return node;
}
10、设置指定位置的元素
先获取结点,在设置元素值;
void PutElem(List *list,int index,Elem elem)
{
asser(index >= 0 && index < list -> length);
DaulNode *node = GetNode(list,index);
node -> elem = elem;
}
11、遍历双链表
void listVisit(List *list)
{
DaulNode *node;
DaulNode *dummy = &list -> dummy;
for(node = dummy -> next; node != dummy;node = node -> next){
printf(" %d <-->",node -> elem);
}
printf("\n");
}
12、已知数值找位置
int LocateElem(List *list,Elem targetElem)
{
DaulNode *node;
DaulNode *dummy = &list -> dummy;
int index = 0;
for(node = dummy -> next; node != dummy; node = node -> next){
if(node -> elem == elem)
return index;
index++;
}
}
13、在指定位置插入元素
void InsertElem(List *list,int index,Elem elem)
{
assert(index >= 0 && index <= list -> length);
DaulNode *node = nodeNew(elem);
DaulNode *next = GetNode(list,index);
DaulNode *prev = next -> prev;
nodeLink(prev,node,next);
list -> length++:
}
14、尾部添加元素
void AppendElem(List *list,Elem elem)
{
int length = listLength(list);
InsertElem(list,length,elem);
}
15、删除指定位置的结点
void DeleteElem(List *list,int index)
{
assert(index >= 0 && index <= list -> length);
DaulNode *node = GetNode(list,index);
nodeUnlink(node);
nodeDelete(node);
list -> length--;
这些就是关于双链表的基本操作了。