数据结构:带头的双循环链表的实现
双向循环链表的结构图
list.h
-
创建一个结构体有头节点head的空链表
-
再创建一个结构体,元素有两个指针分别指向该元素的前一个元素和后一个元素,即该元素的前驱和后继
-
接着定义出双向循环链表的各个功能,给出所需的参数
#ifndef _LIST_H_
#define _LIST_H_
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
#include<stdlib.h>
#define ElemType int
typedef struct DCListNode
{
ElemType data;
struct DCListNode *next;
struct DCListNode *prev;
}DCListNode;
typedef struct DCList
{
DCListNode *head;
}DCList;
static DCListNode* _Buydnode(ElemType x);
void DCListInit(DCList *plist);
void DCListPushBack(DCList *plist, ElemType x);
void DCListPushFront(DCList *plist, ElemType x);
void DCListShow(DCList *plist);
void DCListPopBack(DCList *plist);
void DCListPopFront(DCList *plist);
DCListNode* DCListFind(DCList *plist, ElemType key);
size_t DCListLength(DCList *plist);
void DCListClear(DCList *plist);
void DCListDestroy(DCList *plist);
void DCListDeleteByVal(DCList *plist, ElemType key);
void DCListInsertByVal(DCList *plist, ElemType x);
void DCListReverse(DCList *plist);
void DCListSort(DCList *plist);
void Swap(ElemType *a, ElemType *b)
{
ElemType tmp = *a;
*a = *b;
*b = tmp;
}
#endif /* _LIST_H_ */
Dclist.h
- 给出各功能模块的具体实现
#ifndef _DCLIST_H_
#define _DCLIST_H_
#include"list.h"
//带头的双循环链表
static DCListNode* _Buydnode(ElemType x)
{
DCListNode *s = (DCListNode*)malloc(sizeof(DCListNode));
assert(s != NULL);
s->data = x;
s->next = s->prev = s;
return s;
}
void DCListInit(DCList *plist)
{
plist->head = _Buydnode(0);
}
void DCListPushBack(DCList *plist, ElemType x)
{
assert(plist != NULL);
DCListNode *s = _Buydnode(x);
s->prev = plist->head->prev;
s->prev->next = s;
s->next = plist->head;
plist->head->prev = s;
}
void DCListPushFront(DCList *plist, ElemType x)
{
assert(plist != NULL);
DCListNode *s = _Buydnode(x);
s->next = plist->head->next;
s->prev = plist->head;
s->next->prev = s;
plist->head->next = s;
}
void DCListShow(DCList *plist)
{
assert(plist != NULL);
DCListNode *p = plist->head->next;
while (p != plist->head)
{
printf("%d->", p->data);
p = p->next;
}
printf("Over.\n");
}
void DCListPopBack(DCList *plist)
{
assert(plist != NULL);
DCListNode *p = plist->head->prev;
if (p == plist->head)
return;
plist->head->prev = p->prev;
p->prev->next = plist->head;
free(p);
}
void DCListPopFront(DCList *plist)
{
assert(plist != NULL);
DCListNode *p = plist->head->next;
if (p == plist->head)
return;
plist->head->next = p->next;
p->next->prev = plist->head;
free(p);
}
DCListNode* DCListFind(DCList *plist, ElemType key)
{
assert(plist != NULL);
DCListNode *p = plist->head->next;
while (p != plist->head && p->data != key)
p = p->next;
if (p != plist->head)
return p;
return NULL;
}
size_t DCListLength(DCList *plist)
{
assert(plist != NULL);
size_t len = 0;
DCListNode *p = plist->head->next;
while (p != plist->head)
{
len++;
p = p->next;
}
return len;
}
void DCListClear(DCList *plist)
{
assert(plist != NULL);
DCListNode *p = plist->head->next;
while (p != plist->head)
{
p->next->prev = p->prev;
p->prev->next = p->next;
free(p);
p = plist->head->next;
}
}
void DCListDestroy(DCList *plist)
{
DCListClear(plist);
free(plist->head); //释放头结点
plist->head = NULL;
}
void DCListDeleteByVal(DCList *plist, ElemType key)
{
assert(plist != NULL);
DCListNode *p = DCListFind(plist, key);
if (p == NULL)
return;
p->next->prev = p->prev;
p->prev->next = p->next;
free(p);
}
void DCListInsertByVal(DCList *plist, ElemType x)
{
assert(plist != NULL);
DCListNode *p = plist->head->next;
while (p != plist->head && p->data < x)
p = p->next;
DCListNode *s = _Buydnode(x);
s->next = p;
s->prev = p->prev;
p->prev->next = s;
p->prev = s;
}
void DCListReverse(DCList *plist)
{
assert(plist != NULL);
DCListNode *p = plist->head->next;
DCListNode *q = p->next;
//断开链表
p->next = plist->head;
plist->head->prev = p;
while (q != plist->head)
{
p = q;
q = q->next;
p->next = plist->head->next;
p->prev = plist->head;
p->next->prev = p;
p->prev->next = p; // plist->head->next = p;
}
}
void DCListSort(DCList *plist)
{
assert(plist != NULL);
DCListNode *p = plist->head->next;
DCListNode *q = p->next;
p->next = plist->head;
plist->head->prev = p;
while (q != plist->head)
{
p = q;
q = q->next;
//寻找p的插入位置
DCListNode *t = plist->head->next;
while (t != plist->head && t->data < p->data)
t = t->next;
p->next = t;
p->prev = t->prev;
p->next->prev = p;
p->prev->next = p;
p = q;
}
}
#endif /* _DCLIST_H_ */
main.cpp
- 主函数功能调用
#define _CRT_SECURE_NO_WARNINGS 1
#include"Dclist.h"
int main()
{
DCList mylist;
DCListInit(&mylist);
DCListNode *p;
ElemType item, key;
int select = 1;
int pos = 0;
while (select)
{
printf("***********************************************\n");
printf("* [1] push_back [2] push_front *\n");
printf("* [3] show_list [0] quit_system *\n");
printf("* [4] pop_back [5] pop_front *\n");
printf("* [*6] insert_pos [7] insert_val *\n");
printf("* [*8] delete_pos [9] delete_val *\n");
printf("* [10] find_val [11] length *\n");
printf("* [*12] capacity [13] sort *\n");
printf("* [14] reverse [15] clear *\n");
printf("* [16] remove_all *\n");
printf("***********************************************\n");
printf("请选择:>");
scanf("%d", &select);
if (select == 0)
break;
switch (select)
{
case 1:
printf("请输入要插入的值[以-1结束]:>");
while (scanf("%d", &item), item != -1)
{
DCListPushBack(&mylist, item);
}
break;
case 2:
printf("请输入要插入的值[以-1结束]:>");
while (scanf("%d", &item), item != -1)
{
DCListPushFront(&mylist, item);
}
break;
case 3:
DCListShow(&mylist);
break;
case 4:
DCListPopBack(&mylist);
break;
case 5:
DCListPopFront(&mylist);
break;
case 6:
printf("请输入要插入的位置:>");
scanf("%d", &pos);
printf("请输入要插入的数据:>");
scanf("%d", &item);
//SeqListInsertByPos(&mylist, pos, item);
break;
case 7:
//DCListSort(&mylist);
printf("请输入要插入的数据:>");
scanf("%d", &item);
DCListInsertByVal(&mylist, item);
break;
case 8:
printf("请输入要删除的位置:>");
scanf("%d", &pos);
//SeqListDeleteByPos(&mylist, pos);
break;
case 9:
printf("请输入要删除的值:>");
scanf("%d", &key);
DCListDeleteByVal(&mylist, key);
break;
case 10:
printf("请输入要查找的值:>");
scanf("%d", &key);
p = DCListFind(&mylist, key);
if (p == NULL)
printf("要查找的值不存在.\n");
else
printf("要查找的值为:> %d\n", p->data);
break;
case 11:
printf("seqlist len = %d\n", DCListLength(&mylist));
break;
case 12:
//printf("seqlist capacity = %d\n", SeqListCapacity(&mylist));
break;
case 13:
DCListSort(&mylist);
printf("双循环链表排序成功......\n");
break;
case 14:
DCListReverse(&mylist);
break;
case 15:
DCListClear(&mylist);
printf("清除数据表成功......\n");
break;
case 16:
printf("请输入要删除的值:>");
scanf("%d", &key);
//SeqListRemoveAll(&mylist, key);
break;
}
}
DCListDestroy(&mylist);
printf("GoodBye......\n");
return 0;
}