线性表的两种实现(附C与java代码)

傷城~ 2023-07-11 08:49 15阅读 0赞

2.1 认识线性表

线性表的定义:用数据元素的有限序列表示

同一线性表中的元素必定具有相同特性。

线性表中的数据元素可以为简单类型,也可以为复杂类型

线性表基本操作:

  • 初始化
  • 取值
  • 查找
  • 插入
  • 删除
  • 是否为空
  • 线性表长度

2.2 线性表的顺序存储结构实现(数组实现)

C语言中我们定义一个数据结构是通过结构体的定义来实现

  1. #define MAXSIZE 100 //定义最大长度
  2. typedef int ElemType;
  3. //表示 ElemType是int类型,typedef 是起别名的意思
  4. typedef struct ListCollection{
  5. ElemType Data[MAXSIZE];
  6. // 一种自定义的数据类型,也可以是基本类型
  7. int index;
  8. }*List;
  9. //*List是指向ListCollection这个结构体的一个指针,起别名

而在Java中我们通过类class来实现,后面的方法也是在Java类实现,就是写一个类,带上各种方法

  1. public class ListCollection{
  2. int[] Data;
  3. int index;
  4. }
  • 初始化操作

    //C语言的初始化操作,首先需要申请一块内存空间
    List MakeList(){

    1. List list;
    2. list = (List)malloc(sizeof(struct ListCollection)); //申请一块空间
    3. list->index=-1; // 让长度变为-1,说明里面没有元素,即下标为index
    4. return list;

    }

    // java的初始化操作,通过构造方法
    ListCollection(int max){

    1. Data = new int[max];
    2. index = -1;

    }

  • 是否为空

    //C语言实现,对于C语言不用boolean,用0表示false,1是true
    int isEmpty(List list){

    1. return list->index < 0 ? 1 : 0;

    }

    //java 实现
    boolean isEmpty(){

    1. return index < 0 ? true: false;

    }

  • 获取长度

    //C语言实现
    int getSize(List list){

    1. return list->index;

    }

    //java实现 复杂度O(1)
    int getSize(){

    1. return index;

    }

  • 取值

    //C语言实现
    ElemType getValue(int i,List list){

    1. if(i>list->index||i<0) return -1;
    2. return list->Data[i];

    }

    //java 实现 复杂度O(1)
    int getValue(int i){

    1. if(i>index||i<0) return -1;
    2. return Data[i];

    }

  • 查找

    //C语言实现,复杂度O(n)
    int find(ElemType value,List list){

    1. int i;
    2. if(isEmpty(list)) return -1;
    3. for(i=0;i <= list->index;++i){
    4. if(list->Data[i]==value) return i;
    5. }
    6. return -1;

    }

    // 简单线性查找,复杂度O(n)
    int find(int value){

    1. if(isEmpty()) return -1;
    2. for(int i = 0;i <= index; ++i){
    3. if(Data[i]==value) return i;
    4. }
    5. return -1;

    }

  • 插入

    // C语言实现
    int insert(int i,ElemType value,List list){

    1. int j;
    2. if(list->index==MAXSIZE-1){
    3. printf("已满");
    4. return 0;
    5. }
    6. if(i>list->index+1||i<0){
    7. printf("插入位置不正确");
    8. return 0;
    9. }
    10. for(j=list->index;j>=i;--j){
    11. list->Data[j+1]=list->Data[j];
    12. }
    13. list->Data[i]=value;
    14. list->index++;
    15. return 1;

    }

    //java 实现 复杂度O(n)
    boolean insert(int i,int value){

    1. if(i>index+1||i<0||index==Data.length()-1)
    2. return false;// i的位置不合法,或者线性表已满
    3. for(int j=index;j>=i;--j){
    4. Data[j+1] = Data[j];
    5. // 从后往前遍历,将上一个值赋给下一个
    6. }
    7. Data[i]=value;
    8. index++;
    9. return true;

    }

  • 删除

    // c语言实现 复杂度O(n)
    int deleteData(int i,List list){

    1. int j;
    2. if(i>list->index||i<0||list->index<0){
    3. printf("位置出错或咩有元素");
    4. return 0;
    5. }
    6. for(j=i;j<list->index;++j){
    7. list->Data[j]=list->Data[j+1];
    8. }
    9. list->--;
    10. return 1;

    }

    // java实现
    boolean delete(int i){

    1. if(isEmpty()||i>index||i<0){
    2. return false;//为空或者位置不合法
    3. for(int j=i;j<index;++j){
    4. Data[j]=Data[j+1];
    5. //从删除的位置开始,下一个的值赋给上一个。
    6. }
    7. index--;
    8. return true;

    }

C语言实现的另一种写法

  1. #include <stdlib.h>
  2. #include <iostream>
  3. #define MAXSIZE 100
  4. using namespace std;
  5. typedef int ElemType;
  6. typedef struct Node{
  7. ElemType *elem;
  8. int index;
  9. }*ArrList;
  10. void makeList(ArrList list);
  11. int size(ArrList list);
  12. ElemType get(int i,ArrList list);
  13. void set(int i,int value,ArrList list);
  14. int insert(int i,int value,ArrList list);
  15. int deletes(int i,ArrList list);
  16. int main(){
  17. }
  18. void makeList(ArrList list){
  19. list->elem=new ElemType[MAXSIZE];
  20. if(!list->elem) return NULL;
  21. list->index=0;
  22. }
  23. int size(ArrList list){
  24. if(!list) return 0;
  25. return list->index;
  26. }
  27. ElemType get(int i,ArrList list){
  28. if(i<=0||i>list->index) return -1;
  29. return list->elem[i];
  30. }
  31. void set(int i,ElemType value,ArrList list){
  32. if(i<=0||i>list->index) return ;
  33. list->elem[i]=value;
  34. }
  35. int insert(int i,ElemType value,ArrList list){
  36. int j;
  37. if(list->index==MAXSIZE) return -1; //线性表已满,无法插入
  38. if(i<=0||i>list->index+1) return -1; //位置越界
  39. for(j=list->index;j>=i;--j){
  40. list->elem[j+1]=list->elem[j];
  41. }
  42. list->elem[i]=value;
  43. list->index++;
  44. return 1;
  45. }
  46. int deletes(int i,ArrList list){
  47. int j;
  48. if(i<=0||i>list->index) return -1;
  49. for(j=i;j<list->index;++j){
  50. list->elem[j]=list->elem[j+1];
  51. }
  52. list->index--;
  53. return 1;
  54. }

2.3 线性表实现 (链表实现)

  • 链表的特点:
  1. 逻辑上相邻的数据元素在物理上不一定相邻
  2. 访问时只能通过头指针进入链表,并通过每个结点的指针域向后扫描其余结点。
  3. 数据元素的个数可以自由扩充
  4. 插入、删除等操作不必移动数据,只需修改链接指针
  5. 存储密度小,
    存取效率不高,必须采用顺序存取,即存取数据元素时,只能按链表的顺序进行访问

    • 三个概念(头指针,头结点,首结点):
      头指针:是指向链表中第一个结点的指针。
      头结点: 是一个链表的开头,头结点的数据域可以为空,也可存放线性表长度等附加信息,但此结点不能计入链表长度值。(可有可无)
      首结点:链表真正存储数据的第一个结点。
      在这里插入图片描述
    • 分类:单链表,循环链表,双向链表等

      • 单链表: 单链表中每一个结点由数据域和指针域构成,成一条链,(只能访问后继结点不能访问前趋结点)
        链表结束的条件:link->next==NULL;

    //定义
    struct LinkedList{

    1. ElemType data;
    2. struct LinkList *next;

    }
    //或者
    typedef struct LinkedList{

    1. Elemtype data;
    2. Linked next;

    }*Linked;

循环链表:分为单循环链表和双循环链表,
单循环链表与单链表类似,让最后结点的指针域指头结点。

对循环链表,有时不给出头指针,而给出尾指针可以更方便的找到第一个和最后一个结点
定义与单链表或者双向链表一致,只需要最后结点指向头结点即可
结束条件判断:link->next!=info;(不等于头结点或者是首结点)

双向链表:一个结点中有两个指针域一个数据域,指针域分别指向下一个结点和上一个结点。

  1. //定义
  2. typedef struct DuLNode{
  3. ElemType data;
  4. struct DuLNode *prior;
  5. struct DuLNode *next;
  6. }DuLNode, *DuLinkList

如图:

在这里插入图片描述
线性表单链表代码实现

  1. //宏定义
  2. #define OK 1
  3. #define ERROR 0
  4. #define OVERFLOW -2
  5. //定义
  6. typedef int ElemType;
  7. typedef int Status;
  8. typedef struct LinkedList *Link;
  9. struct LinkedList{
  10. ElemType data;
  11. Link next;
  12. };
  13. //方法体
  14. Link CreateInputLinked(int n);
  15. int size(Link link);
  16. Link get(Link link,int i);
  17. void set(Link link,int i,ElemType value);
  18. Status insert(Link link,int i,ElemType value);
  19. Status drop(Link link,int i);
  20. void OutputLink(Link link);
  21. Status DestroyList(Link link);
  22. int main(){
  23. return 0;};
  24. //初始化加输入
  25. Link CreateInputLinked(int n){
  26. Link head,temp,node,info;
  27. head = new LinkedList;
  28. info = new LinkedList;
  29. head->next=info;
  30. info->next = NULL;
  31. temp = info;
  32. while(n-->0){
  33. node = new LinkedList;
  34. cin>>node->data;
  35. node->next=NULL;
  36. temp->next=node;
  37. temp=temp->next;
  38. }
  39. return head;
  40. }
  41. //取长度
  42. int size(Link link){
  43. Link temp = link->next->next;
  44. int count=0;
  45. while(temp){
  46. count++;
  47. temp = temp->next;
  48. }
  49. return count;
  50. }
  51. // 获得第i个结点
  52. Link get(Link link,int i){
  53. Link temp = link->next->next;
  54. int count = 1;
  55. while(temp&&count<i){
  56. temp = temp->next;
  57. count++;
  58. }
  59. return count==i ? temp : NULL;
  60. }
  61. //修改第i个结点的数据域
  62. void set(Link link,int i,ElemType value){
  63. Link temp = link->next->next;
  64. int count = 1;
  65. while(temp&&count<i){
  66. temp = temp->next;
  67. count++;
  68. }
  69. if(count==i) temp->data=value;
  70. }
  71. //插入操作
  72. Status insert(Link link,int i,ElemType value){
  73. Link left,node;
  74. if(i==1){
  75. left = link->next;
  76. }else{
  77. left = get(link,i-1);
  78. }
  79. if(!left) return ERROR;
  80. node = new LinkedList;
  81. node->data=value;
  82. node->next = left->next;
  83. left->next = node;
  84. return OK;
  85. }
  86. //删除操作
  87. Status drop(Link link,int i){
  88. Link left,mid;
  89. if(i==1){
  90. left =link->next;
  91. }else{
  92. left = get(link,i-1);
  93. }
  94. if(!left) return ERROR;
  95. mid = left->next;
  96. left->next=mid->next;
  97. delete mid;
  98. return OK;
  99. }
  100. //输出操作
  101. void OutputLink(Link link){
  102. Link temp = link->next->next;
  103. while(temp){
  104. cout<<temp->data<<" ";
  105. temp=temp->next;
  106. }
  107. cout<<endl;
  108. }
  109. //销毁
  110. Status DestroyList(Link link){
  111. Link tmp;
  112. while(link){
  113. tmp=link;
  114. link=link->next;
  115. delete tmp;
  116. }
  117. return OK;
  118. }

java实现(java只要理解到this本身就是头指针,并且在使用时先初始化再取得当前对象的next,才不会出现NullPointerExpetion,与C语言略微不同)

  1. class NodeList{
  2. int Data;
  3. NodeList Next ;
  4. boolean isEmpty(){
  5. //判断是否为空
  6. if(this.Next==null) return true;
  7. return false;
  8. }
  9. int size(){
  10. // 取长度
  11. NodeList link=this.Next.Next;
  12. if(this.isEmpty()) return 0;
  13. int i=0;
  14. while(link!=null){
  15. link=link.Next;
  16. i++;
  17. }
  18. return i;
  19. }
  20. NodeList getValue(int i){
  21. //获取第i个结点
  22. if(i>size()||i<0) return null;
  23. NodeList link =this.Next;
  24. int p = 0;
  25. while(p<i&&link!=null){
  26. link=link.Next;
  27. ++p;
  28. }
  29. if(p==i) return link;
  30. else return null;
  31. }
  32. void setValue(int i,int value){
  33. // 修改第i个值
  34. NodeList tmp = getValue(i);
  35. if(tmp==null) return;
  36. tmp.Data=value;
  37. }
  38. boolean insert(int i,int value){
  39. //插入一个新结点
  40. if(i<0&&i>size()+1) return false;
  41. NodeList left;
  42. if(i==1){
  43. left = this.Next;
  44. }else {
  45. left = getValue(i-1);
  46. }
  47. if(left==null) return false;
  48. NodeList tmp = new NodeList();
  49. tmp.Data=value;
  50. tmp.Next=left.Next;
  51. left.Next=tmp;
  52. return true;
  53. }
  54. boolean delete(int i){
  55. //删除一个结点
  56. if(i<0||i>size()) return false;
  57. NodeList left;
  58. if(i==1){
  59. left = this;
  60. }else {
  61. left = getValue(i-1);
  62. }
  63. if(left==null) return false;
  64. NodeList tmp =left.Next;
  65. left.Next = tmp.Next;
  66. return true;
  67. }
  68. void Output(){
  69. //输出,因为this代表头指针,要两次next才能找到首结点,中间隔了一个头结点
  70. NodeList link = this.Next.Next;
  71. while(link!=null){
  72. System.out.print(link.Data+" ");
  73. link=link.Next;
  74. }
  75. System.out.println();
  76. }
  77. void Input(int n){
  78. // 输入操作,先初始化再赋值给结点.next,避免空指针异常
  79. Scanner input =new Scanner(System.in);
  80. NodeList link =new NodeList();
  81. this.Next=link;
  82. while(n-->0){
  83. NodeList node =new NodeList();
  84. node.Data=input.nextInt();
  85. link.Next=node;
  86. link=link.Next;
  87. }
  88. }
  89. }

发表评论

表情:
评论列表 (有 0 条评论,15人围观)

还没有评论,来说两句吧...

相关阅读