双向链表(非循环)

来源:互联网 发布:数据分析师cda通过率 编辑:程序博客网 时间:2024/06/06 00:20

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。



1、头文件(dilst.h)

#pragma once//带头结点的双向链表(非循环)typedef struct DNode{int data;//数据域struct DNode *next;//后继指针struct DNode *prio;//前驱指针}DNode,*DList;//初始化双向链表void InitDList(DList plist);//头插bool Insert_head(DList plist,int val);//尾插bool Insert_tail(DList plist,int val);//查找DNode *Search(DList plist,int key);//删除bool Delete(DList plist,int key);//获取长度(数据结点的个数)int GetLength(DList plist);//判空bool IsEmpty(DList plist);//清空void Clear(DList plist);//摧毁void Destroy(DList plist);//打印void Show(DList plist);//逆置void Reverse(DList plist);


2、源文件(dlist.cpp)

#include<stdio.h>#include<stdlib.h>#include<assert.h>#include"dlist.h"//初始化双向链表void InitDList(DList plist){assert(plist != NULL);if(plist == NULL){return ;}plist->next = NULL;plist->prio = NULL;}//头插bool Insert_head(DList plist,int val){assert(plist != NULL);if(plist == NULL){return false;}DNode *p = (DNode *)malloc(sizeof(DNode));p->data = val;p->next = plist->next;plist->next = p;p->prio = plist;if(p->next != NULL){p->next->prio = p;}return true;}//尾插bool Insert_tail(DList plist,int val){assert(plist != NULL);if(plist == NULL){return false;}DNode *p = (DNode *)malloc(sizeof(DNode));p->data = val;DNode *q;for(q = plist;q->next != NULL;q = q->next);//找尾巴//将p插在q的后面p->next = q->next;q->next = p;p->prio = q;return true;}//查找DNode *Search(DList plist,int key){assert(plist != NULL);if(plist == NULL){return false;}for(DNode *p = plist->next;p != NULL;p = p->next){if(p->data == key){return p;}}return NULL;}//删除bool Delete(DList plist,int key){assert(plist != NULL);if(plist == NULL){return false;}DNode *p = Search(plist,key);if(p == NULL){return false;}p->prio->next = p->next;if(p->next != NULL){p->next->prio = p->prio;}free(p);return true;}//获取长度(数据结点的个数)int GetLength(DList plist){int count = 0;for(DNode *p = plist->next;p != NULL;p = p->next){count++;}return count;}//判空bool IsEmpty(DList plist){return plist->next == NULL;}//清空void Clear(DList plist){Destroy(plist);}//摧毁void Destroy(DList plist){DNode *p;while(plist->next != NULL){p = plist->next;plist->next = p->next;free(p);}}//打印void Show(DList plist){for(DNode *p = plist->next;p != NULL;p = p->next){printf("%d ",p->data);}printf("\n");}//逆置void Reverse(DList plist){DNode *p = plist->next;DNode *q;int tmp;for(q = plist;q->next != NULL;q = q->next);//找尾巴for(int i = 0;i < GetLength(plist)/2;i++){tmp = p->data;p->data = q->data;q->data = tmp;p = p->next;q = q->prio;}}


3、测试源文件(test.cpp)

#include<stdio.h>#include<vld.h>//测试内存泄漏的头文件#include"dlist.h"int main(){DNode head1;DNode head2;InitDList(&head1);InitDList(&head2);for(int i = 0;i < 10;i++){Insert_head(&head1,i);Insert_tail(&head2,i);}Show(&head1);Show(&head2);printf("%d\n",Delete(&head1,3));printf("%d\n",GetLength(&head2));Destroy(&head1);Destroy(&head1);Reverse(&head2);Show(&head2);return 0;}