/* 链式表示的线性表 定义:采用一组任意储存单元存放线性表的元素,这组存储单元可以是 连续的,也可以是不连续的。 1.单链表 2.循环单链表 3.双向链表 以单链表为基础,单链表的每一个节点有一个数据域和一个指针域,指 针域存放的是下一个节点的地址,而尾节点的指针域为NULL,他有一个 头结点,头结点没有数据,只用于存放链表首节点(第一个节点)的地 址,即确定一个单链表,只需要一个信息,积极头节点的地址。 循环单链表是一种首位相连的单链表,将单链表尾节点的指针域由空指 针改为指向头结点或者第一个节点,整个链表就形成一个环。 双向链表就是链表中每个节点有两个指针域,一个指向前驱节点,另一 个指向直接后继节点。 双向链表 和 循环链表 结合就形成了双向循环链表。 */ # include <stdio.h> # include <stdlib.h> # include <malloc.h> // 单向链表 typedef struct list { int data; // 链表数据域 struct list * pNext; }Node, * pNode; // 链表的创建 pNode Create_List(); // 链表的遍历 void Travel_List(pNode); // 判断链表是否为空 bool Is_Empty(pNode); // 计算链表长度 int Length_List(pNode); // 链表节点的插入, 形参为链表头地址 在哪个位置前插入 插入的节点的值 void Insert_List(pNode, int, int); // 链表节点的删除,形参为链表头地址,需要删除的节点的位置 void Delete_List(pNode, int); // 链表的排序 void Seq_List(pNode); // 链表的销毁 void Destroy_List(pNode); int main(void) { pNode pHead = Create_List(); Travel_List(pHead); int pos, val; printf("请输入需要插入的位置及该的数据! "); scanf("%d %d", &pos, &val); Insert_List(pHead, pos, val); Travel_List(pHead); printf("请输入需要删除的位置! "); scanf("%d %d", &pos); Delete_List(pHead, pos); Travel_List(pHead); Destroy_List(pHead); return 0; } pNode Create_List(void) { int len; printf("请输入您需要的链表长度:"); scanf("%d", &len); pNode pHead = (pNode)malloc(sizeof(Node)); if (NULL == pHead) { printf("动态内存分配失败! "); exit(-1); } pHead->pNext = NULL; pNode pNew, pTemp; pNew = pHead; for (int i = 0; i < len; ++i) { pTemp = (pNode)malloc(sizeof(Node)); if (NULL == pTemp) { printf("动态内存分配失败! "); exit(-1); } pTemp->pNext = NULL; pNew->pNext = pTemp; printf("请输入此节点储存的数据:"); scanf("%d", &pTemp->data); printf(" "); pNew = pNew->pNext; } return pHead; } void Travel_List(pNode pHead) { pNode pTemp; while (pHead->pNext != NULL) { pTemp = pHead->pNext; printf("%-5d ", pTemp->data); pHead = pHead->pNext; } return; } bool Is_Empty(pNode pHead) { if (NULL == pHead->pNext) return true; else return false; } int Length_List(pNode pHead) { int cnt = 0; // 记录链表长度 while (NULL != pHead->pNext) { ++cnt; pHead = pHead->pNext; } return cnt; } void Insert_List(pNode pHead, int pos, int val) { // 首先要判定被插入的位置是否存在 pNode pTemp = pHead; int i = 0; // 说明:此循环结束后pTemp记录的是第pos-1个节点的地址 while (NULL != pTemp && i < pos-1) { pTemp = pTemp->pNext; ++i; } if (NULL == pTemp || i > pos-1) { printf("插入失败! "); exit(-1); } pNode pNew; pNew = (pNode)malloc(sizeof(Node)); if (NULL == pNew) { printf("动态内存分配失败! "); exit(-1); } pNew->data = val; pNew->pNext = pTemp->pNext; pTemp->pNext = pNew; return; } void Delete_List(pNode pHead, int pos) { pNode pTemp = pHead; int i = 0; while (NULL != pTemp && i < pos-1) { pTemp = pTemp->pNext; ++i; } if (NULL == pTemp || i > pos-1) { printf("删除失败! "); exit(-1); } pNode pTemp1 = pTemp->pNext; int val = pTemp1->data; pTemp->pNext = pTemp1->pNext; printf("被删除的节点数据为:%d ", val); return; } void Seq_List(pNode pHead) { pNode pTemp, pTemp1, pTemp2, pTemp3, pMax, pMax1, pMax2; pTemp = pHead; // 表示要开始用来比较的原节点的前一个节点地址 pTemp1 = pTemp->pNext; // 表示开始用来比较的原节点的地址 while (NULL != pTemp1->pNext) { pMax1 = pTemp; // 追踪最大值前面的节点 pMax = pTemp1; // 用来追踪最大值的节点 pTemp2 = pMax; // 用于追踪被比较点前一个点的地址 pTemp3 = pMax->pNext; // 用于追踪被比较点 while (NULL != pTemp2->pNext) { if (pMax->amount < pTemp3->amount) { pMax1 = pTemp2; pMax = pTemp3; } pTemp2 = pTemp2->pNext; if (NULL != pTemp2->pNext) pTemp3 = pTemp2->pNext; } pMax1->pNext = pMax->pNext; pMax->pNext = pTemp1; pTemp->pNext = pMax; pTemp = pMax; pTemp1 = pTemp->pNext; } return; } void Destroy_List(pNode pHead) { pNode pTemp; while (pHead != NULL) { pTemp = pHead->pNext; free(pHead); pHead = pTemp; } return; }