-
定义
-
n个节点离散
-
彼此通过指针相连
-
每个节点只有一个前驱节点;也只有一个后续节点
-
首节点没有前驱节点,尾节点没有后续节点
-
-
注意区别
—为什么引入头节点?
——为了便于对链表的操作
- 头节点:第一个有效节点之前的节点,头节点并不存放有效数据,头节点的数据类型和首节点的一样
- 头指针:指向头节点的指针变量
- 首节点:第一个有效节点
- 尾节点:最后一个有效节点,指针域为NULL
- 尾指针:指向尾节点的指针变量
—确定一个量表需要几个参数?
——仅需头指针即可,其他信息都可求
-
分类
- 单链表
- 双链表:每个节点有两个指针域
- 循环链表:表中最后一个结点的指针域指向头结点,整个链表形成一个环
- 非循环链表
-
对链表的操作
-
创建
-
遍历
-
插入节点
-
删除节点
-
查找
-
销毁
-
求长度
-
排序
#include<stdio.h> #include<malloc.h> #include<stdlib.h> typedef struct Node { //数据域 int data; //指针域 struct Node * pNext;//因为它要指向的是下一个节点(struct Node类型) }NODE,*PNODE; /* NODE等价于 struct Node *PNODE等价于struct Node * */ PNODE createList(); //创建链表,并返回头指针 void traverseList(PNODE); //遍历输出 bool isEmpty(PNODE); //判空 int lengthList(PNODE); //求链表长度 bool insertList(PNODE,int,int); //插入元素 bool deleteList(PNODE,int,int *); //删除元素 void sortList(PNODE); //从大到小排序 int main() { PNODE pHead = NULL;//等价于struct Node * pHead = NULL int val; pHead = createList();//创建一个非循环单链表,并将该链表的头节点返回,赋给pHead printf("原链表:-------------\n"); traverseList(pHead); if(isEmpty(pHead)) { printf("该链表为空"); } printf("链表的长度是:%d\n",lengthList(pHead)); printf("排序:-------------\n"); sortList(pHead); traverseList(pHead); printf("插入:-------------\n"); insertList(pHead,4,100); traverseList(pHead); printf("删除:-------------\n"); if(deleteList(pHead,4,&val)) { printf("删除成功,您删除了元素:%d",val); } else { printf("删除失败"); } return 0; } PNODE createList(void) { int len; int val;//用来临时存放用户输入的节点的值 PNODE pHead = (PNODE)malloc(sizeof(NODE));//分配了一个不存放一个有效数据的头节点 if(NULL == pHead) { printf("内存不足,分配失败\n"); exit(-1); } printf("请输入您要生成的链表节点个数:len = "); scanf("%d",&len); PNODE pTail = pHead; //这里和 57 59行是关键 pTail->pNext = NULL; for(int i = 0;i<len;i++) { printf("请输入第%d个节点的值:",i+1); scanf("%d",&val); PNODE pNew = (PNODE)malloc(sizeof(NODE)); if(NULL == pNew) { printf("内存不足,分配失败\n"); exit(-1); } pNew->data = val; pTail->pNext = pNew;//pTail永远指向尾节点 57行 pNew->pNext = NULL; pTail = pNew; //59行 } return pHead; } void traverseList(PNODE pHead) { PNODE pTemp = pHead->pNext; while(pTemp!= NULL) { printf("%d\n",pTemp->data); pTemp = pTemp->pNext; } return; } bool isEmpty(PNODE pHead) { if(pHead->pNext==NULL) { return true; } else return false; } int lengthList(PNODE pHead) { int count = 0; PNODE p = pHead->pNext; while(p!=NULL) { count++; p = p->pNext; } return count; } void sortList(PNODE pHead) { int temp; PNODE p; int i,j; int len = lengthList(pHead); if(!isEmpty(pHead)) { for(i = 1;i<len;i++) { for(j = 0,p = pHead->pNext;j<len-i;j++,p = p->pNext) { if(p->data < p->pNext->data) { temp = p->data; p->data = p->pNext->data; p->pNext->data = temp; } } } } } //在pHead所指向的链表的第pos个节点的前面插入一个新的节点,该节点的值是val,并且pos的值是从1开始的 bool insertList(PNODE pHead,int pos,int val) { int i = 0; PNODE p = pHead; while(NULL!=p&&i<pos-1) { p = p->pNext; i++; } if(i>pos-1||NULL == p) { return false; } PNODE pNew = (PNODE)malloc(sizeof(NODE)); if(NULL == pNew) { printf("内存不足,分配失败\n"); exit(-1); } pNew->data = val; PNODE q = p->pNext; p->pNext = pNew; pNew->pNext = q; return true; } bool deleteList(PNODE pHead,int pos,int * pVal) { int i = 0; PNODE p = pHead; while(NULL!=p->pNext&&i<pos-1) { p = p->pNext; i++; } if(i>pos-1||NULL == p->pNext) { return false; } PNODE q = p->pNext; *pVal = q->data; //删除p节点后面的节点 p->pNext = q->pNext; free(q); q=NULL; return true; }
-
-
算法
- 狭义的算法与数据的存储方式有关
- 广义的算法与数据的存储方式无关
- 泛型:
- 利用某种技术使得不同的数据存储方式,执行操作一致
-
链表的优缺点
链式存储——链表及相关操作
最新推荐文章于 2023-01-01 21:16:00 发布