链式线性表

学习了顺序线性表后,我开始有一个疑问,每一次的插入和删除都需要大量的移动数据吗,有没有一种方法可以不移动数据呢?这就是本章要学习的新的数据结构,线性表的链式存储方式,记不记得第一章就说过的,对于一种数据结构,其逻辑结构是唯一的,但是它可能对应着多种存储结构。链式结构就是线性表的另外一种存储结构

链式结构是什么样子呢

见过火车吧?火车就是一个车厢扣着一个车厢的,简单的说火车的车厢就相当于单链表的一个节点,这个车厢有什么特点呢,

1.当前车厢的乘客

2.勾着下个车厢的钩子

用数据结构怎么描述火车车厢呢,如下

[html] view plaincopy

  1. typedef struct Node
  2. {
  3. int value[MAXSIZE];//数组用来装乘客
  4. struct Node * next; //勾着下个车厢的钩子
  5. }Node;

有了这个车厢我们是不是可以来构造一列火车了

先来创建个火车头,一开始后车头后面一节车厢都没有所以它勾着空气(NULL)

[cpp] view plaincopy

  1. void InitNode(Node * &node)
  2. {
  3. node = (Node *)malloc(sizeof(Node));
  4. memset(node->value,0,sizeof(node->value));
  5. node->next=NULL;
  6. }

接着一节节车厢要接入,那就得创建个插入车厢的方法

[cpp] view plaincopy

  1. void InsertNode(Node *&head,int index,Node *node )
  2. {
  3. int nodeIndex=0;
  4. Node *ptr=head;
  5. if(head->next!=NULL)
  6. {
  7. while(nodeIndex<index-1&&ptr!=NULL)
  8. {
  9. ptr=ptr->next;
  10. nodeIndex++;
  11. }
  12. if(ptr!=NULL)
  13. {
  14. node->next= ptr->next;
  15. ptr->next=node;
  16. }
  17. }
  18. else
  19. {
  20. head->next=node;
  21. }
  22. }

上面的算法对于初学者可能不是那么容易看得懂:思路主要是先判断这个链表中是不是只有火车头,如果是的话,那么就直接将火车头的钩子勾住新车厢
(x),如果火车头已经有勾着车厢了,那么找到要插入车厢x的位置的前一个车厢(a),然后把(x)勾住(a)的后一个车厢(b),再让(a)勾住
(x),这样子说是不是晕了,我也晕了,我当时老师也是这么说的,所以也晕了,好吧,看个图就明白了

x本来要插在a的后面b的前面,所以先让x->b,然后a->x,有的图话好理解多了吧!!!!

车厢接入完毕了,现在如果有车厢报废要撤下来呢,应该怎做?这次直接上图

要删除车厢b先把a勾住c,然后把b毁掉,就是这么简单

算法描述如下

[cpp] view plaincopy

  1. void DeleteNode(Node *&head,int index )
  2. {
  3. int nodeIndex=0;
  4. Node *ptr=head;
  5. while(nodeIndex<index-1&&ptr!=NULL)
  6. {
  7. ptr=ptr->next;
  8. nodeIndex++;
  9. }
  10. if(ptr!=NULL)
  11. {
  12. Node *ptrBeDel=ptr->next;
  13. if(ptrBeDel!=NULL)
  14. {
  15. ptr->next= ptrBeDel->next;
  16. free(ptrBeDel);
  17. }
  18. }
  19. }

好了下面贴出完整的代码,不过对于链表的讨论这里还是很简单,还有很多方法是没有实现的,下面的方法有兴趣可以思考下为什么插入车厢后输出的顺序是逆的,怎么让它变成顺序输出?提示:这就是头插入法和尾插入法的区别,由于篇幅有限无法全部多写出来

[cpp] view plaincopy

  1. #include <iostream>
  2. #include <malloc.h>
  3. #include <string.h>
  4. #define MAXSIZE 50
  5. typedef struct Node
  6. {
  7. int value[MAXSIZE];//数组用来装乘客
  8. struct Node * next; //勾着下个车厢的钩子
  9. }Node;
  10. void InitNode(Node * &node)
  11. {
  12. node = (Node *)malloc(sizeof(Node));
  13. memset(node->value,0,sizeof(node->value));
  14. node->next=NULL;
  15. }
  16. void CreateNodeList(Node * &head)
  17. {
  18. void InsertNode(Node *&head,int index,Node *node );
  19. Node *node;
  20. for(int i=1;i<10;i++)
  21. {
  22. node=(Node *)malloc(sizeof(Node));
  23. for(int j=0;j<MAXSIZE;j++)
  24. {
  25. node->value[j]=i;
  26. }
  27. node->next=NULL;
  28. InsertNode(head,1,node);
  29. }
  30. }
  31. void InsertNode(Node *&head,int index,Node *node )
  32. {
  33. int nodeIndex=0;
  34. Node *ptr=head;
  35. if(head->next!=NULL)
  36. {
  37. while(nodeIndex<index-1&&ptr!=NULL)
  38. {
  39. ptr=ptr->next;
  40. nodeIndex++;
  41. }
  42. if(ptr!=NULL)
  43. {
  44. node->next= ptr->next;
  45. ptr->next=node;
  46. }
  47. }
  48. else
  49. {
  50. head->next=node;
  51. }
  52. }
  53. void DeleteNode(Node *&head,int index )
  54. {
  55. int nodeIndex=0;
  56. Node *ptr=head;
  57. while(nodeIndex<index-1&&ptr!=NULL)
  58. {
  59. ptr=ptr->next;
  60. nodeIndex++;
  61. }
  62. if(ptr!=NULL)
  63. {
  64. Node *ptrBeDel=ptr->next;
  65. if(ptrBeDel!=NULL)
  66. {
  67. ptr->next= ptrBeDel->next;
  68. free(ptrBeDel);
  69. }
  70. }
  71. }
  72. int main()
  73. {
  74. Node *head;
  75. InitNode(head);
  76. CreateNodeList(head);
  77. while(head!=NULL)
  78. {
  79. std::cout<<"第"<<head->value[0]<<"车厢,"<<"乘客的票号都是"<< head->value[0]<<std::endl;
  80. head=head->next;
  81. }
  82. return 0;
  83. }
时间: 2024-10-03 22:40:31

链式线性表的相关文章

链式线性表实现

1.链式线性表头文件 #ifndef _LINK_LIST_H #define _LINK_LIST_H //定义一个节点 typedef struct _tag_LinkListNode { _tag_LinkListNode *next; }LinkListNode; //定义一个链表@1链表包含一个头部节点@ 包含链表的长度 typedef struct _LinkList { LinkListNode Head; int nLen;//长度 }LinkList; LinkList *li

双向链式线性表(模板实现)

线性表(List):零个或者多个数据元素的有限序列. 线性表的存储结构大约分为三种:1,顺序存储结构 2,链式存储结构 3,静态链表. 顺序存储结构的线性表是由数组实现的,由于C++不支持变长数组,所以顺序存储结构的线性表在定义时就指定了长度,这是一个很大的问题.譬如说,一个顺序存储结构的线性表的长度为10000,我们写程序用到了这个线性表,但是只往表里添加了十几个数据,这显然对空间造成了极大的浪费.所以说,这种结构的线性表并适用于实际的应用. 链式存储结构的线性表实现了空间的动态分配,这一概念

java实现的链式线性表结构

package com.hephec.ds; public class LinkedList<T> { //定义一个内部类节点Node Node实例代表链表的节点 class Node{ //保存节点的数据 private T data; //保存下一个节点的引用 private Node next; //无参的构造方法 public Node(){ } //有参的构造方法 public Node(T data,Node next){ this.data=data; this.next=nex

7-19 求链式线性表的倒数第K项

7-19 求链式线性表的倒数第K项(20 分) 给定一系列正整数,请设计一个尽可能高效的算法,查找倒数第K个位置上的数字. 输入格式: 输入首先给出一个正整数K,随后是若干正整数,最后以一个负整数表示结尾(该负数不算在序列内,不要处理). 输出格式: 输出倒数第K个位置上的数据.如果这个位置不存在,输出错误信息NULL. 输入样例: 4 1 2 3 4 5 6 7 8 9 0 -1 输出样例: 7思路:待定 原文地址:https://www.cnblogs.com/zengguoqiang/p/

3-05. 求链式线性表的倒数第K项(15)(STL list运用)

题目链接:http://pat.zju.edu.cn/contests/ds/3-05 给定一系列正整数,请设计一个尽可能高效的算法,查找倒数第K个位置上的数字. 输入格式说明: 输入首先给出一个正整数K,随后是若干正整数,最后以一个负整数表示结尾(该负数不算在序列内,不要处理). 输出格式说明: 输出倒数第K个位置上的数据.如果这个位置不存在,输出错误信息"NULL". 样例输入与输出: 序号 输入 输出 1 4 1 2 3 4 5 6 7 8 9 0 -1 7 2 6 3 6 7

C++ 模版类的单向链式线性表

先上代码!以后再仔细编辑! 头文件 <span style="font-size:18px;">#pragma once template<typename EleType> class ChainList { public: struct Node { EleType _data; Node* _next; Node(){ _next = nullptr; } Node(EleType data){ _data = data; _next = nullptr;

7-19 求链式线性表的倒数第K项(20 分)(单链表定义与尾插法)

给定一系列正整数,请设计一个尽可能高效的算法,查找倒数第K个位置上的数字. 输入格式: 输入首先给出一个正整数K,随后是若干正整数,最后以一个负整数表示结尾(该负数不算在序列内,不要处理). 输出格式: 输出倒数第K个位置上的数据.如果这个位置不存在,输出错误信息NULL. 输入样例: 4 1 2 3 4 5 6 7 8 9 0 -1 输出样例: 7 解题思路:寻找倒数第K项,这里所用的方法是定义两个指针,让第一个指针先走k步,然后两个指针一起移动,第一个指针移到末尾的时候,第二个指针就到了倒数

7-1 求链式线性表的倒数第K项 (20 分)

给定一系列正整数,请设计一个尽可能高效的算法,查找倒数第K个位置上的数字. 输入格式: 输入首先给出一个正整数K,随后是若干正整数,最后以一个负整数表示结尾(该负数不算在序列内,不要处理). 输出格式: 输出倒数第K个位置上的数据.如果这个位置不存在,输出错误信息NULL. 输入样例: 4 1 2 3 4 5 6 7 8 9 0 -1 输出样例: 7 #include <stdio.h> #include <malloc.h> int main() { int K, temp, l

C++ 模版类的单向循环链式线性表

基于之前做的单向链式线性表http://blog.csdn.net/shiwazone/article/details/47000191,改进下,实现了循环链表,相对应单向链表,循环链表将尾节点的指针域指向头节点,加入循环,可以让我们在查找某一个index的节点时,可以先判断一下位置和链表长度的关系,如果index处于链表的前半部分,我们可以从头节点遍历查找,如果处于后半部分,我们可以从尾节点往前查找,当然此时我们需要使用双向链表.双向链表的操作,下次给出吧!循环链表给了我们一种思路,如果我们在