![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<stdio.h> #include<stdlib.h> #define TRUE 1 #define OK 1 #define FALSE 0 #define ERROR 0 #define NULL 0 #define OVERFLOW 0 typedef int ElemType; typedef int Status; typedef struct DbLNode { ElemType data; DbLNode *prior,*next; }DbLNode,*DbLinkList; //函数声明 Status CreateList(DbLinkList &L);//初始化链表 Status ClearList(DbLinkList L);//清空表 Status DestroyList(DbLinkList &L);//销毁双向链表 Status IsEmpty(DbLinkList L);//判断表是否为空 int GetLength(DbLinkList L);//判断表的长度 Status GetElemValue(DbLinkList L,int i,ElemType &e);//返回第i个元素的值 int LocateElem(DbLinkList L,ElemType e,Status(*compare)(ElemType,ElemType));//返回L中第1个与e满足关系compare()的数据元素的位序 Status GetPrevElemValue(DbLinkList L,ElemType cur_e,ElemType &pre_e);//前驱判断 Status GetNextElemValue(DbLinkList L,ElemType cur_e,ElemType &next_e);//后继判断 DbLinkList GetElem(DbLinkList L,int i);//返回第i个元素的地址 Status Insert(DbLinkList L,int i,ElemType e);//在表的第i个位置之前插入元素e Status DeleteNode(DbLinkList L,int nPos);//删除表中第i个元素 void TraverseForward(DbLinkList L,void(*visit)(ElemType));//正序对每个元素调用函数visit() void TraverseBack(DbLinkList L,void(*visit)(ElemType));//逆序对每个元素调用函数visit() void print(ElemType e); Status SortList(DbLinkList L); Status ReverseList(DbLinkList L);
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <stdio.h> #include "dblinklist.h" #include "gtest.h" //产生空的双向循环链表 Status CreateList(DbLinkList &L) { L = (DbLinkList)malloc(sizeof(DbLNode)); if(L) { L->next = L->prior=L; L->data = 0; } else { return ERROR; } return OK; } //清空链表(清空有效节点)头结点仍然存在 Status ClearList(DbLinkList L) { DbLNode* pCur = L->next; while(pCur != L) { pCur = pCur->next; free(pCur->prior); pCur->prior = NULL; } L->next = L->prior = L; return OK; } //连头结点也不留,全部咔嚓 Status DestroyList(DbLinkList &L) { ClearList(L); free(L); L=NULL; return OK; } //判断表是否为空 Status IsEmpty(DbLinkList L) { return (L->next == L && L->prior == L); } //返回表的长度 int GetLength(DbLinkList L) { int nLen = 0; DbLNode* p = L->next; while(p != L) { nLen++; p = p->next; } return nLen; } //获取第nPos个元素,将值赋给e Status GetElemValue(DbLinkList L,int nPos,ElemType &elem) { int nCur = 1; DbLNode* pCur = L->next;//p指向第一个结点 while(pCur != L && nCur < nPos)//顺指针向后查找,直到p指向第nPos个元素 { nCur++; pCur = pCur->next; } if(pCur == L || nCur > nPos) { return ERROR; } elem = pCur->data; return OK; } //返回表中第1个与e满足关系compare()的数据元素的位置 int LocateElem(DbLinkList L,ElemType e,Status(*compare)(ElemType,ElemType)) { int nPos = 0; DbLNode* pCur = L->next; while(pCur != L)//p未指向头结点 { nPos++;//计数器加1 if(compare(pCur->data,e)) { //找到这样的元素 return nPos; } pCur = pCur->next; } return -1; } Status GetPrevElemValue(DbLinkList L,ElemType curElem,ElemType &prevElem) { DbLNode* pCur = L->next->next;//p指向第2个元素 while(pCur != L) { if(pCur->data == curElem)//p指向值为cur_e的结点 { prevElem = pCur->prior->data;//将p的前驱结点的值赋给 return OK; } pCur = pCur->next; } return ERROR; } Status GetNextElemValue(DbLinkList L,ElemType curElem,ElemType &nextElem) { DbLNode* pCur = L->next->next;//p指向第二个元素 while(pCur != L) { if(pCur->prior->data == curElem)//p所指结点的前驱指向cur_e { nextElem = pCur->data;//将p所指结点的值赋给next_e return OK; } pCur = pCur->next; } return ERROR; } //在双向链表中返回第i个元素的节点指针 DbLNode* GetElem(DbLinkList L,int nPos) { //异常判断 if(nPos < 0||nPos > GetLength(L)) { return NULL; } int nIndex = 1; DbLNode* p = L;//p指向头结点 for(nIndex = 1; nIndex <= nPos; nIndex++)//p指向第i个结点 { p = p->next;//p指向下一个结点 } return p; } //在链表第i个位置上插入元素 Status Insert(DbLinkList L,int nPos,ElemType elem) { DbLNode *pCur = NULL; DbLNode *pNew = NULL; if(nPos < 1 || nPos > GetLength(L) + 1) { return ERROR; } pCur = GetElem(L,nPos-1);//在L中确定第i个结点前驱的位置指针p if(!pCur) { return ERROR; } pNew = (DbLNode*)malloc(sizeof(DbLNode));//生成新结点 if(!pNew) { return ERROR; } pNew->data = elem;//将e赋给新的结点 pNew->prior = pCur;//新结点的前驱为第i-1个结点 pNew->next = pCur->next;//新结点的后继为第i个结点 pCur->next->prior = pNew;//第i个结点的前驱指向新结点 pCur->next = pNew;//第i-1个结点的后继指向新结点 return OK; } //删除第i个结点 Status DeleteNode(DbLinkList L,int nPos) { if(nPos < 1) { return ERROR; } DbLNode* pDel = NULL; pDel = GetElem(L,nPos);//在L中确定第i个元素的位置指针 if(!pDel) { return ERROR; } pDel->prior->next = pDel->next;//第原i-1个结点的后继指向原第i+1个结点 pDel->next->prior = pDel->prior;//第原i+1个结点的前驱指向原第i-1个结点 free(pDel); pDel = NULL; return OK; } //由双向循环链表的表头出发,正序对每个数据元素调用函数visit() void TraverseForward(DbLinkList L,void(*visit)(ElemType)) { DbLNode* pCur = L->next;//p指向首元结点 while(pCur != L) { visit(pCur->data);//对p所指结点调用函数visit() pCur = pCur->next; } printf("\n"); } //由双向循环链表的表头出发,逆序对每个元素调用函数visit() void TraverseBack(DbLinkList L,void(*visit)(ElemType)) { DbLinkList pCur = L->prior;//p指向尾结点 while(pCur != L) { visit(pCur->data); pCur = pCur->prior; } printf("\n"); } void print(ElemType e) { printf("%3d",e); } //链表排序,冒泡 Status SortList(DbLinkList L) { if (IsEmpty(L)) { return ERROR; } DbLNode *p = L->next; DbLNode *q = NULL; for (; p != L; p = p->next) { for (q = p->next; q != L; q = q->next) { if (p->data > q->data) { int nTemp = p->data; p->data = q->data; q->data = nTemp; } } } return OK; } //链表逆序 Status ReverseList(DbLinkList L) { if (IsEmpty(L)) { return ERROR; } DbLNode *pCur = L->next; L->prior = L->next = L; DbLNode *pNew = NULL; while (pCur != L) { pNew = pCur; pCur = pCur->next; pNew->prior = L; pNew->next = L->next; L->next->prior = pNew; L->next = pNew; } L->prior = pCur->prior; return OK; } ///// int main(int argc, char* argv[]) { /*testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS();*/ DbLinkList L = NULL; CreateList(L); for (int i = 0; i < 5; ++i) { Insert(L,1,i); } if (!Insert(L,10,10)) { printf("Insert Failed\n"); } printf("Before Sort:\n"); TraverseForward(L,print); SortList(L); printf("After Sort:\n"); TraverseForward(L,print); printf("After Reverse:\n"); ReverseList(L); TraverseForward(L,print); printf("插入元素测试\n"); int nPos = 0; int nElem = 0; while (nPos != -1) { scanf("%d",&nPos); scanf("%d",&nElem); printf("插入元素: pos = %d,Elem = %d\n",nPos,nElem); if (Insert(L,nPos,nElem)) { TraverseForward(L,print); } else { printf("Insert Failed\n"); } } printf("插入元素测试完毕\n"); return 0; }