Written with StackEdit中文版.
双向链表
简介
为克服单链表、循环链表的单向性,即如果要查询结点的直接前驱需要从表头指针出发,双向链表中的结点具有两个指针域:其一指向直接后继,另一指向直接前驱
声明与定义
1 2 3 4 5 6 7 8 9 10 11 12
| #define OK 1 #define ERROR 0 typedef int ElemType; typedef int Status;
typedef struct DuLNode { ElemType data; struct DuLNode* prior; struct DuLNode* next; }DuLNode, * DuLinkList;
|
相关方法
手动输入n个元素的值,创建一个双向链表L
注意是用返回值接收链表L
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| DuLinkList CreateList_L(int n){ DuLNode* end, * p, * L; L = (DuLinkList)malloc(sizeof(DuLNode)); if (L == NULL){ return ERROR; } end = L; for (int i = 0; i < n; i++){ p = (DuLinkList)malloc(sizeof(DuLNode)); if (p == NULL){ return ERROR; } scanf_s("%d", &p->data); end->next = p; p->prior = end; end = p; } end->next = L; L->prior = end; return L; }
|
返回链表L的第i个元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Status GetElem_L(DuLinkList* L, int i,ElemType* e){ DuLinkList p; p = (DuLinkList)malloc(sizeof(DuLNode)); p = (*L)->next; int j = 1; while (p && j < i){ p = p->next; ++j; } if (!p || j > i || p == *L){ printf("第%d个元素不存在或该结点是头结点!\n", i); return ERROR; } *e = p->data; return OK; }
|
在链表L的第i个位置插入元素e
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| Status ListInsert_DuL(DuLinkList* L, int i, ElemType e){ DuLinkList p; p = (DuLinkList)malloc(sizeof(DuLNode)); p = *L; int j = 0;
while (p && j < i) { p = p->next; ++j; } if (!p || j > i || p == *L) { printf("第%d个元素不存在或该结点是头结点!\n", i); return ERROR; } DuLinkList s; s = (DuLinkList)malloc(sizeof(DuLNode)); if (s != NULL){ s->data = e; s->prior = p->prior; p->prior->next = s; s->next = p; p->prior = s; return OK; } return ERROR; }
|
删除链表L的第i个元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| Status ListDelete_DuL(DuLinkList *L, int i, ElemType* e){ DuLinkList p; p = (DuLinkList)malloc(sizeof(DuLNode)); p = *L; int j = 0; while (p->next && j < i - 1) { p = p->next; ++j; } if (!(p->next) || j > i - 1 || p->next == *L) { printf("删除的位置不合理!\n"); return ERROR; } p = p->next; *e = p->data; p->prior->next = p->next; p->next->prior = p->prior; free(p); return OK; }
|
链表排序函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| Status SelectSort(DuLinkList *L){ printf("开始对链表进行冒泡排序!\n"); DuLinkList p, q, small; DuLNode* head = *L; ElemType temp, temp1;
for (p = (*L)->next; p->next != head; p = p->next) { small = p; for (q = p->next; q != head; q = q->next) { if (q->data < small->data) small = q; } if (small != p) { temp = p->data; p->data = small->data; small->data = temp; } } return OK; }
|
顺序遍历链表的所有元素
1 2 3 4 5 6 7 8 9 10
| void ListTraverse(DuLinkList L) { DuLNode* p = L; printf("遍历双向链表的全部元素: "); while (L->next != p){ L = L->next; printf("%d ", L->data); } printf("\n"); }
|
方法测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| int main(void) { DuLinkList MyList; int size = 0; int pos = 0; ElemType e = 0;
printf("输入链表的大小: "); scanf_s("%d", &size); printf("根据大小按顺位序对双向链表赋值\n"); MyList = CreateList_L(size); ListTraverse(MyList); printf("需要返回双向链表第几位的元素:"); scanf_s("%d", &pos); GetElem_L(&MyList, pos, &e); printf("链表第%d位的元素是:%d\n", pos, e);
printf("需要向双向链表第几位插入元素:"); scanf_s("%d", &pos); printf("需要插入的元素是:"); scanf_s("%d", &e); ListInsert_DuL(&MyList, pos, e); ListTraverse(MyList);
printf("需要删除双向链表的第几位元素: "); scanf_s("%d", &pos); ListDelete_DuL(&MyList, pos, &e); printf("被删除的元素是:%d\n", e); ListTraverse(MyList);
SelectSort(&MyList); ListTraverse(MyList); return 0; }
|