赞
踩
摘要: 双向链表比单链表稍复杂, 也更不常用. 主要是为了练习链表的变种, 寻找更多设计的感觉. 这样在面对实际问题的时候, 就具有一定的建模能力.
#include <stdio.h> #include <malloc.h> /** * Double linked list of integers. The key is char. */ typedef struct DoubleLinkedNode{ char data; struct DoubleLinkedNode *previous; struct DoubleLinkedNode *next; } DLNode, *DLNodePtr; /** * Initialize the list with a header. * @return The pointer to the header. */ DLNodePtr initLinkList(){ DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode)); tempHeader->data = '\0'; tempHeader->previous = NULL; tempHeader->next = NULL; return tempHeader; }// Of initLinkList /** * Print the list. * @param paraHeader The header of the list. */ void printList(DLNodePtr paraHeader){ DLNodePtr p = paraHeader->next; while (p != NULL) { printf("%c", p->data); p = p->next; }// Of while printf("\r\n"); }// Of printList /** * Insert an element to the given position. * @param paraHeader The header of the list. * @param paraChar The given char. * @param paraPosition The given position. */ void insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition){ DLNodePtr p, q, r; // Step 1. Search to the position. p = paraHeader; for (int i = 0; i < paraPosition; i ++) { p = p->next; if (p == NULL) { printf("The position %d is beyond the scope of the list.", paraPosition); return; }// Of if } // Of for i // Step 2. Construct a new node. q = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode)); q->data = paraChar; // Step 3. Now link. r = p->next; q->next = p->next; q->previous = p; p->next = q; if (r != NULL) { r->previous = q; }// Of if }// Of insertElement /** * Delete an element from the list. * @param paraHeader The header of the list. * @param paraChar The given char. */ void deleteElement(DLNodePtr paraHeader, char paraChar){ DLNodePtr p, q, r; p = paraHeader; // Step 1. Locate. while ((p->next != NULL) && (p->next->data != paraChar)){ p = p->next; }// Of while // Step 2. Error check. if (p->next == NULL) { printf("The char '%c' does not exist.\r\n", paraChar); return; }// Of if // Step 3. Change links. q = p->next; r = q->next; p->next = r; if (r != NULL) { r->previous = p; }// Of if // Step 4. Free the space. free(q); }// Of deleteElement /** * Unit test. */ void insertDeleteTest(){ // Step 1. Initialize an empty list. DLNodePtr tempList = initLinkList(); printList(tempList); // Step 2. Add some characters. insertElement(tempList, 'H', 0); insertElement(tempList, 'e', 1); insertElement(tempList, 'l', 2); insertElement(tempList, 'l', 3); insertElement(tempList, 'o', 4); insertElement(tempList, '!', 5); printList(tempList); // Step 3. Delete some characters (the first occurrence). deleteElement(tempList, 'e'); deleteElement(tempList, 'a'); deleteElement(tempList, 'o'); printList(tempList); // Step 4. Insert to a given position. insertElement(tempList, 'o', 1); printList(tempList); }// Of appendInsertDeleteTest /** * Address test: beyond the book. */ void basicAddressTest(){ DLNode tempNode1, tempNode2; tempNode1.data = 4; tempNode1.next = NULL; tempNode2.data = 6; tempNode2.next = NULL; printf("The first node: %d, %d, %d\r\n", &tempNode1, &tempNode1.data, &tempNode1.next); printf("The second node: %d, %d, %d\r\n", &tempNode2, &tempNode2.data, &tempNode2.next); tempNode1.next = &tempNode2; }// Of basicAddressTest /** * The entrance. */ void main(){ insertDeleteTest(); basicAddressTest(); }// Of main
Hello!
The char 'a' does not exist.
Hll!
Holl!
The first node: 1703632, 1703632, 1703640
The second node: 1703620, 1703620, 1703628
Press any key to continue
麦尔哈巴·阿卜杜拉同学的代码, 注释写得详细.
#include<bits/stdc++.h> using namespace std; typedef int Status; typedef int ElemType; #define OVERFLOW -1 #define ERROR 0 #define OK 1 //-----双向链表的储存结构----- typedef struct DuLNode { ElemType data; struct DuLNode *prior; struct DuLNode *next; } DuLNode, *DuLinkList; DuLinkList L; //1、双向链表初始化 Status InitList_DuL(DuLinkList &L) { //构造一个空的双向链表L L = new DuLNode; L->prior = NULL; L->next = NULL; return OK; } //2、双向链表按位查找 DuLNode *GetElem_DuL(DuLinkList L, int i) { DuLNode *p = L->next; int j = 1; while(p && j < i) { p = p->next; j++; } if(!p || j > i) return NULL; else return p; } //3、双向链表前驱 Status PriorElem_DuL(DuLinkList L, ElemType cur_e, ElemType &pre_e) { DuLNode *p; if(!(p = LocateElem_DuL(L, cur_e))) //在L中确定第i个元素的位置指针p return ERROR; pre_e = p->prior->data; return OK; } //4、双向链表后继 Status NextElem_DuL(DuLinkList L, ElemType cur_e, ElemType &next_e) { DuLNode *p; if(!(p = LocateElem_DuL(L, cur_e))) //在L中确定第i个元素的位置指针p return ERROR; next_e = p->next->data; return OK; } //5、双向链表插入 Status ListInsert_DuL(DuLinkList &L, int i, ElemType e) { //在带头结点的双向链表L中第i个位置之前插入元素e DuLNode *p; if(!(p = GetElem_DuL(L, i))) return ERROR; DuLNode *s = new DuLNode; s->data = e; s->prior = p->prior; p->prior->next = s; s->next = p; p->prior = s; return OK; } //11、双向链表删除 Status ListDelete_DuL(DuLinkList &L, int i) { //删除带头结点的双向链表L中的第i个元素 DuLNode *p; if(!(p = GetElem_DuL(L, i))) return ERROR; p->prior->next = p->next; p->next->prior = p->prior; delete p; return OK; } int main() { cout<<"------------------------双向链表菜单----------------------"<<'\n'; cout<<"操作0:退出程序"<<'\n'; cout<<"操作1:创建一个带头结点的双向链表,且遍历此链表"<<'\n'; cout<<"操作2:在双向链表中的第i个结点前插入一个结点值为e的正整数"<<'\n'; cout<<"操作3:删除双向链表链表中的第j个结点"<<'\n'; int a, n, flag = 1; while(flag) { cout<<'\n'<<"请选择要执行的操作:"; while(cin>>a) { if(a < 0 || a > 5) cout<<"请选择正确操作编号:"; else break; } switch(a) { case 0: { cout<<"感谢使用本程序,祝您生活愉快!"<<'\n'; flag = 0; break; } case 1: { cout<<"----菜单-----"<<'\n'; cout<<"操作1:前插法"<<'\n'; cout<<"操作2:后插法"<<'\n'; cout<<"-------------"<<'\n'; cout<<"请选择单链表的创建方式:"; int b; while(cin>>b) { if(b != 1 && b != 2) cout<<"请选择正确操作编号:"; else break; } cout<<"请输入要建立的单链表的元素个数:"; cin>>n; if(b == 1) { cout<<"请按逆位序依次输入这"<<n<<"个元素:"; CreateList_H_DuL(L, n); } else if(b == 2) { cout<<"请按正位序依次输入这"<<n<<"个元素:"; CreateList_R_DuL(L, n); } cout<<"单链表创建完毕:"; TraverseList_DuL(L); break; } case 2: { int i; ElemType e; cout<<"在单链表中的第i个结点前插入一个结点值为e的正整数,请依次输入i和e的值:"; cin>>i>>e; if(ListInsert_DuL(L, i, e)) { cout<<"单链表插入完毕:"; TraverseList_DuL(L); } else cout<<"i值不合法!"<<'\n'; break; } case 3: { int j; cout<<"删除单链表中的第j个结点,请输入j的值:"; cin>>j; if(ListDelete_DuL(L, j)) { cout<<"单链表删除完毕:"; TraverseList_DuL(L); } else cout<<"j值不合法!"<<'\n'; break; } } } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。