学习了顺序线性表后,我开始有一个疑问,每一次的插入和删除都需要大量的移动数据吗,有没有一种方法可以不移动数据呢?这就是本章要学习的新的数据结构,线性表的链式存储方式,记不记得第一章就说过的,对于一种数据结构,其逻辑结构是唯一的,但是它可能对应着多种存储结构。链式结构就是线性表的另外一种存储结构
链式结构是什么样子呢
见过火车吧?火车就是一个车厢扣着一个车厢的,简单的说火车的车厢就相当于单链表的一个节点,这个车厢有什么特点呢,
1.当前车厢的乘客
2.勾着下个车厢的钩子
用数据结构怎么描述火车车厢呢,如下
[html] view plaincopy
- typedef struct Node
- {
- int value[MAXSIZE];//数组用来装乘客
- struct Node * next; //勾着下个车厢的钩子
- }Node;
有了这个车厢我们是不是可以来构造一列火车了
先来创建个火车头,一开始后车头后面一节车厢都没有所以它勾着空气(NULL)
[cpp] view plaincopy
- void InitNode(Node * &node)
- {
- node = (Node *)malloc(sizeof(Node));
- memset(node->value,0,sizeof(node->value));
- node->next=NULL;
- }
接着一节节车厢要接入,那就得创建个插入车厢的方法
[cpp] view plaincopy
- void InsertNode(Node *&head,int index,Node *node )
- {
- int nodeIndex=0;
- Node *ptr=head;
- if(head->next!=NULL)
- {
- while(nodeIndex<index-1&&ptr!=NULL)
- {
- ptr=ptr->next;
- nodeIndex++;
- }
- if(ptr!=NULL)
- {
- node->next= ptr->next;
- ptr->next=node;
- }
- }
- else
- {
- head->next=node;
- }
- }
上面的算法对于初学者可能不是那么容易看得懂:思路主要是先判断这个链表中是不是只有火车头,如果是的话,那么就直接将火车头的钩子勾住新车厢
(x),如果火车头已经有勾着车厢了,那么找到要插入车厢x的位置的前一个车厢(a),然后把(x)勾住(a)的后一个车厢(b),再让(a)勾住
(x),这样子说是不是晕了,我也晕了,我当时老师也是这么说的,所以也晕了,好吧,看个图就明白了
x本来要插在a的后面b的前面,所以先让x->b,然后a->x,有的图话好理解多了吧!!!!
车厢接入完毕了,现在如果有车厢报废要撤下来呢,应该怎做?这次直接上图
要删除车厢b先把a勾住c,然后把b毁掉,就是这么简单
算法描述如下
[cpp] view plaincopy
- void DeleteNode(Node *&head,int index )
- {
- int nodeIndex=0;
- Node *ptr=head;
- while(nodeIndex<index-1&&ptr!=NULL)
- {
- ptr=ptr->next;
- nodeIndex++;
- }
- if(ptr!=NULL)
- {
- Node *ptrBeDel=ptr->next;
- if(ptrBeDel!=NULL)
- {
- ptr->next= ptrBeDel->next;
- free(ptrBeDel);
- }
- }
- }
好了下面贴出完整的代码,不过对于链表的讨论这里还是很简单,还有很多方法是没有实现的,下面的方法有兴趣可以思考下为什么插入车厢后输出的顺序是逆的,怎么让它变成顺序输出?提示:这就是头插入法和尾插入法的区别,由于篇幅有限无法全部多写出来
[cpp] view plaincopy
- #include <iostream>
- #include <malloc.h>
- #include <string.h>
- #define MAXSIZE 50
- typedef struct Node
- {
- int value[MAXSIZE];//数组用来装乘客
- struct Node * next; //勾着下个车厢的钩子
- }Node;
- void InitNode(Node * &node)
- {
- node = (Node *)malloc(sizeof(Node));
- memset(node->value,0,sizeof(node->value));
- node->next=NULL;
- }
- void CreateNodeList(Node * &head)
- {
- void InsertNode(Node *&head,int index,Node *node );
- Node *node;
- for(int i=1;i<10;i++)
- {
- node=(Node *)malloc(sizeof(Node));
- for(int j=0;j<MAXSIZE;j++)
- {
- node->value[j]=i;
- }
- node->next=NULL;
- InsertNode(head,1,node);
- }
- }
- void InsertNode(Node *&head,int index,Node *node )
- {
- int nodeIndex=0;
- Node *ptr=head;
- if(head->next!=NULL)
- {
- while(nodeIndex<index-1&&ptr!=NULL)
- {
- ptr=ptr->next;
- nodeIndex++;
- }
- if(ptr!=NULL)
- {
- node->next= ptr->next;
- ptr->next=node;
- }
- }
- else
- {
- head->next=node;
- }
- }
- void DeleteNode(Node *&head,int index )
- {
- int nodeIndex=0;
- Node *ptr=head;
- while(nodeIndex<index-1&&ptr!=NULL)
- {
- ptr=ptr->next;
- nodeIndex++;
- }
- if(ptr!=NULL)
- {
- Node *ptrBeDel=ptr->next;
- if(ptrBeDel!=NULL)
- {
- ptr->next= ptrBeDel->next;
- free(ptrBeDel);
- }
- }
- }
- int main()
- {
- Node *head;
- InitNode(head);
- CreateNodeList(head);
- while(head!=NULL)
- {
- std::cout<<"第"<<head->value[0]<<"车厢,"<<"乘客的票号都是"<< head->value[0]<<std::endl;
- head=head->next;
- }
- return 0;
- }