线性结构_链表

来源:互联网 发布:javascript事件委托 编辑:程序博客网 时间:2024/05/16 14:05
1、定义:
n个节点离散分配;
每个节点只有一个前驱结点,每个节点只有一个后续节点;
首节点没有前驱结点,尾节点没有后续节点;

2、专业术语:
头节点:第一个有效节点之前的节点,方便对链表进行操作,并不存放有效数据,头节点的数据类型与首节点一致;
首节点:第一个有效节点;
尾节点:最后一个有效节点;
头指针:指向头节点的指针变量;
尾指针:指向尾节点的指针变量。

3、如果希望通过一个函数来对链表进行处理,我们至少需要接受链表那些信息:
只需要一个参数:头指针,通过头指针可以推算出链表的其他所有信息。

4、分类:
单链表:
双链表:每个节点有2个指针域。
循环链表:能通过任何一个节点找到所有节点。

5、算法:
遍历
查找
清空
销毁
求长度
排序
删除节点
插入节点

(要点,先临时定义一个指向p后面节点的指针r)
(在p后面插入节点q)
r = p->pNext; p->pNext = q;(p指向q) q->qNext = r;(q指向下一个节点)
q->pNext = p->pNext; p->pNext = q;

(删除p后面的节点)
r = p->pNext;
p->pNext = p->pNext->pNext;
free(r);

6、算法:
狭义的算法是与数据的存储方式密切相关的。
广义的算法是与数据的存储方式无关的。
泛型:利用某种技术达到的效果就是:不用的存储方式,执行的操作是一样的。
#include<stdio.h>#include<malloc.h>#include<stdlib.h>typedef struct Node {int data;//数据域struct Node* pNext;//指针域,存放下一个节点的地址} NODE , *PNODE;//NODE相当于struct Node 类型,*PNODE想当与struct Node*类型PNODE create_List(void);//创建非循环单链表void traverse_List(PNODE pHead);//遍历链表bool is_Empty(PNODE pHead);//判断链表是否为空int length_List(PNODE pHead);//求链表的长度bool insert_List(PNODE, int, int);//向链表插入数据,第一个参数是链表的头节点,第二个参数是插入的位置,第三个是插入的值(data)bool delete_List(PNODE, int, int*);//删除某个节点,第一个参数是链表的头节点,第二个参数是删除节点的位置,第三个是删除节点的值(data)void sort_List(PNODE);//对链表进行排序int main() {PNODE pHead = NULL;//等价于 struct Node* pHead = nullpHead = create_List();//创建一个非循环单链表,并把链表首地址赋给pHeadif (is_Empty(pHead)) {printf("该链表为空。\n");}else {printf("链表不为空。\n");int len = length_List(pHead);printf("链表的长度为:%d\n", len);}traverse_List(pHead);//遍历链表sort_List(pHead);traverse_List(pHead);//遍历链表return 0;}PNODE create_List(void) {int len;//链表节点个数int val;//用来临时存放用户输入的数据data//分配了一个不存放有效数据的头节点PNODE pHead = (PNODE)malloc(sizeof(NODE));if (NULL == pHead) {printf("分配失败,程序终止!");exit(-1);}//pTail与pHead都指向头节点PNODE pTail = pHead;//避免当链表节点个数为0,程序崩溃pTail->pNext = NULL;printf("请输入你要生成的链表的节点个数:");scanf("%d", &len);for (int i = 0; i < len; ++i) {printf("请输入第%d个节点的数据:" , i+1);scanf("%d", &val);PNODE pNew = (PNODE)malloc(sizeof(NODE));if (NULL == pHead) {printf("分配失败,程序终止!");exit(-1);}pNew->data = val;//pTali永远指向尾节点pTail->pNext = pNew;//pTail指向新节点pNew->pNext = NULL;//把新节点的指针域清空pTail = pNew;//将新节点pNew放置到pTail}return pHead;}void traverse_List(PNODE pHead) {PNODE p = pHead->pNext;while (NULL != p) {printf("%d ", p->data);p = p->pNext;}printf("\n");return;}bool is_Empty(PNODE pHead) {if (NULL == pHead->pNext) {return true;}else return false;}int length_List(PNODE pHead) {PNODE p = pHead->pNext;int len = 0;while (NULL != p) {len++;p = p->pNext;}return len;}void sort_List(PNODE pHead) {/*简单的冒泡排序int i, j, t;for (i = 0; i < len - 1; i++) {for (j = i + 1; j < len; j++) {if (a[i] > a[j]) {t = a[i];a[i] = a[j];a[j] = t;}}}return;*/int i, j, t;int len = length_List(pHead);PNODE p, q;for (i = 0, p = pHead->pNext; i < len - 1; i++, p = p->pNext) {for (j = i + 1, q = p->pNext; j < len; j++, q = q->pNext) {if (p->data > q->data) {t = p->data;p->data = q->data;q->data = t;}}}return;}

0 0
原创粉丝点击