线性表之离散存储(链表)
来源:互联网 发布:信广立诚贷之家数据 编辑:程序博客网 时间:2024/05/20 06:52
1.什么是链表?
链表和数组都是线性表的分支.逻辑上他们都是相连的。但是在物理上面链表和数组相反,链表具有以下四个性质:
(1)n个节点离散分配(2)节点彼此通过指针相连
(3)每一个节点只有一个前驱节点和一个后驱节点
(4)首节点没有前驱节点 尾节点没有后续节点
2.链表的专业术语?
首节点:第一个有效节点(要有数据域和指针域)
尾节点:最后一个有效节点
头结点:第一个有效节点之前的那个节点
头结点并不存放有效数据(数据域)
它只有指针域,指向首节点
加头结点就是为了方便对链表的操作
头指针:指向头结点的指针变量
尾指针:指向尾节点的指针变量
注意:和数组一样,我们确定一个数组只需要知道首节点的地址,数组的有效长度,数据最大长度.那么确定一个链表需要几个参数呢?
答:只需要一个参数,头指针,知道头指针可以很快知道下面各个节点的信息
3.链表的分类
链表可以分为四类:
单链表:只有一个指针域,它是指向下一个节点
双链表:一个节点有两个指针域,分别指向前后两个节点元素
循环链表:节点与节点之间形成一个环状,可以找到任意一个节点
非循环链表:就是普通的链表(可双可单)
4.链表的算法操作
PNODE createNodeList(int len);//初始化链表(给链表分配len个长度的内存空间)
void showNodeList(PNODE pHead);//显示链表的基本信息
bool is_empty(PNODE pHead);//判断链表是否为空
int NodeList_Length(PNODE pHead);//获得链表的长度
bool insert_NodeList(PNODE pHead,int pos,int val);//在链表指定位置(pos>=1)插入值(val)
bool delete_NodeList(PNODE pHead,int pos);//删除指定位置的数值
bool update_NodeList(PNODE pHead,int pos,int val);//更改指定位置的数值为val
NODE get(PNODE pHead,int pos);//获得指定位置的数值
void sort_NodeList(PNODE pHead);//升序排序
1)初始化链表,先要动态分配len个长度的内存空间给头指针(pHead),然后判断空间是否分配正确,如果正确的话,那么这个头指针也代表尾指针(因为开始只有一个节点)。接着每循环一次创建一个新的节点(pNew),将其挂在尾指针(pTail)后面,如此一来,链表初始化完毕.
//初始化链表PNODE createNodeList(int len){PNODE pTail;int i,val; PNODE pHead = (PNODE)malloc(sizeof(NODE)*len);//动态分类len个长度空间if(pHead==NULL){printf("链表空间分配失败,退出程序!");exit(-1); }pTail = pHead;pTail->pNext=NULL;for(i=0;i<len;i++){PNODE pNew = (PNODE)malloc(sizeof(NODE));printf("请输入第%d个元素的值:",i+1);scanf("%d",&val);pNew->data=val;pTail->pNext=pNew;pNew->pNext=NULL;pTail=pNew;}return pHead;}2)输出链表的基本信息,是通过while循环来判断的,只要是p->pNext不为空,那么就说明整个链表有节点存在,便输出p->data.
//输出链表的值void showNodeList(PNODE pHead){PNODE p = pHead->pNext;int num = NodeList_Length(pHead);if(num!=0){printf("链表的长度为%d,分别为",num);while(p!=NULL){printf("%d ",p->data);p=p->pNext;}printf("\n");}}3)判断链表是否为空,比较简单,只需要判断头指针pHead->pNext是否为空,也就是头指针后面是否有节点就可以了.
//判断链表为不为空bool is_empty(PNODE pHead){PNODE p = pHead->pNext;if(p==NULL)return true;return false;}4)获得链表的长度,先定义一个中间变量num,然后通过while循环判断p->pNext是否为空,不为空就加一,直到不满足循环条件就说明链表已经到头了,长度因此获得.
int NodeList_Length(PNODE pHead){int num=0;PNODE p = pHead->pNext;if(is_empty(pHead))return 0;while(p!=NULL){num++;p=p->pNext;}return num;}5)往链表指定位置插入一个数值,这个算法相对而言比较麻烦。因为链表不像数组那样,可以很快的定位插入的位置,所以链表的插入算法首先要找到插入位置的前一个节点,然后自己要新建一个pNew新节点用来存放想要插入的值,接着将pNew与前一个节点相互连接,pNew与插入位置后一个节点再连接一下,表示插入成功.基本思想就是这样.
//往链表中插入一个元素 bool insert_NodeList(PNODE pHead,int pos,int val){PNODE p = pHead->pNext;PNODE pNew,pTemp;int i=1;if(pos<1||pos>NodeList_Length(pHead)+1)return false;//1 2 34 4 5 6 7 :pos=6while(p!=NULL&&i<pos-1){i++;p=p->pNext;//p已经是第五个节点了 }pNew=(PNODE)malloc(sizeof(NODE));pTemp = p->pNext;pNew->data=val;p->pNext=pNew;pNew->pNext=pTemp;return true;}6)链表的删除节点算法
bool delete_NodeList(PNODE pHead,int pos){int i=1;PNODE pTemp;PNODE p = pHead->pNext;if(p==NULL){printf("链表为空,无法继续删除,退出程序!");return false;}// 1 2 3 4 5 6 pos=3;while(p!=NULL&&i<pos-1){i++;p=p->pNext; //此时的p是要删除的数的前一个 }pTemp = p->pNext;p->pNext = p->pNext->pNext;free(pTemp);return true;}7)链表的更改节点算法
bool update_NodeList(PNODE pHead,int pos,int val){int i=1;PNODE p =pHead->pNext;if(p==NULL){printf("链表为空,无法修改,退出程序!");return false;}while(p!=NULL&&i<pos){i++;p=p->pNext;}p->data=val;return true;}8)获取指定位置的数据(返回节点元素)
NODE get(PNODE pHead,int pos){PNODE p = pHead->pNext;int i=1;while(p!=NULL&&i<pos){i++;p=p->pNext;}return *p;}9)链表排序算法
void sort_NodeList(PNODE pHead){PNODE p,q;int i,j;int length= NodeList_Length(pHead);for(i=0,p=pHead->pNext;i<length-1;i++,p=p->pNext){for(j=i+1,q=p->pNext;j<length;j++,q=q->pNext){if(p->data>q->data){int temp=p->data;p->data=q->data;q->data=temp;}}}}
总结:个人感觉链表算法还是很重要的,因为后面的队列,栈,树都要用到链表,所以链表既是重点又是难点.(这几天一直很忙,更新有点慢,下一篇就是栈和队列)
链表源码下载地址:http://download.csdn.net/download/qq_31308883/10148594
- 线性表之离散存储(链表)
- 线性表之离散存储(链表)
- 数据结构线性结构之离散存储--链表
- 数据结构学习笔记之线性结构--离散存储[链表]
- 第二章(线性表之离散存储)
- 线性结构--离散存储 链表讲解
- 数据结构之线性结构的离散存储(循环列表和双向链表)
- 数据结构之线性结构的离散存储(单链表)
- 10-数据结构_线性结构-离散存储-链表_创建与遍历链表
- 08-数据结构_线性结构-离散存储-链表_1
- 存储管理之离散存储
- 线性表之顺序存储
- 线性表之顺序存储
- 线性表之链式存储
- 线性表--线性存储
- 离散存储---链表
- 离散存储_链表
- 09-数据结构_线性结构-离散存储-链表_插删伪算法
- LeetCode 572. Subtree of Another Tree
- SQL Server数据库之数据库的创建、修改、查看、删除及分离与附加
- 剑指offer第32题(把数组排成最小的数)
- Shell脚本常用参数
- java两年开发工作经验面试总结
- 线性表之离散存储(链表)
- Android多点触控技术
- Kotlin使用EasyRecycleview
- 陀螺仪初探
- Android解析编译之后的所有文件(so,dex,xml,arsc)格式
- javascript:void(0)
- 软件测试_单元测试
- VS2013 64位 32位|Microsoft Visual Studio Ultimate 2013(简体中文旗舰版)
- SQL优化