当前位置:   article > 正文

顺序表的插入,删除,修改和查找(详细解析)_c语言顺序表的初始化,插曲,删除,与查找

c语言顺序表的初始化,插曲,删除,与查找

目录

一.顺序表的初始化----静态分配

二.顺序表的初始化----动态分配

三.顺序表的插入

1.插入操作

2.插入操作的时间复杂度

三.顺序表的删除操作

1.顺序表的删除

 2.删除操作的时间复杂度

四.顺序表的查找

1.按位查找操作:查找第i位置的元素

2.按位查找操作的时间复杂度:O(1)

3.按值查找操作

4.按值查找的时间复杂度


一.顺序表的初始化----静态分配

  1. #include<stdio.h>
  2. #define MaxSize 10
  3. typedef struct{
  4. int data[MaxSize];
  5. int length;
  6. }SqList;
  7. void InitList(SqList &L)
  8. {
  9. for(int i=0;i<length;i++)
  10. L.data[i]=0;
  11. L.length=0;
  12. }
  13. int main()
  14. {
  15. SqList L;
  16. InitList(L);
  17. return 0;
  18. }

不能写为

  1. #include<stdio.h>
  2. #define MaxSize 10
  3. typedef struct{
  4. int data[MaxSize];
  5. int length;
  6. }SqList;
  7. void InitList(SqList &L)
  8. {
  9. L.length=0;
  10. }
  11. int main()
  12. {
  13. SqList L;
  14. InitList(L);
  15. for(int i=0;i<MaxSize;i++)
  16. {
  17. printf("data[%d]=%d\n",i,L.data[i]);
  18. }
  19. return 0;
  20. }

结果为

 其中有两个错误

1.未初始化数据

因为在初始化时没有设置数据元素的默认值,内存中会出现上述“4203657”,“21”这类遗留脏数据

2.i<MaxSize

上述代码中的i<MaxSize操作其实是不合理的,应该访问到顺序表的最后一个元素截止,不应该访问大于数据表长度的元素,即i<L.length

若L.length>MaxSize会报错,若将MaxSize设的稍微大些,有可能造成内存的浪费,所以最好的解决方式就是动态内存分配

二.顺序表的初始化----动态分配

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define InitSize 10
  4. typedef struct{
  5. int *data;//指示动态分配数组的指针:L.data=(int *)malloc(InitSize*sizeof(int));
  6. int MaxSize;//顺序表的最大容量
  7. int length;//顺序表的当前长度
  8. }SeqList;
  9. void InitList(SeqList &L)
  10. {
  11. //申请一段连续的存储空间
  12. L.data=(int*)malloc(InitSize*sizeof(int));
  13. L.length=0;
  14. L.MaxSize=InitSize;
  15. }
  16. //开辟一段新的空间
  17. void IncreaseSize(SeqList &L,int len)
  18. {
  19. int *p=L.data;
  20. L.data=(int *)malloc((L.MaxSize+len)*sizeof(int));
  21. for(int i=0;i<L.length;i++)
  22. {
  23. L.data[i]=p[i];//将数据复制到新区域
  24. //虽然动态分配能让数据表的大小灵活的改变,但是会增大时间开销
  25. }
  26. L.MaxSize=L.MaxSize+len;
  27. free(p);
  28. }
  29. int main()
  30. {
  31. SeqList();
  32. InitList();
  33. IncreaseSize(L,5);
  34. return 0;
  35. }

free函数会将*p(p指针)所指向的整块存储空间释放,归还给系统,同时p是一个局部变量,当这个函数结束后,p这个变量的存储空间也将被释放 

三.顺序表的插入

1.插入操作
  1. #define MaxSize 10 //定义最大长度
  2. typedef int ElemType;
  3. typedef struct
  4. {
  5. ElemType data[MaxSize];
  6. int length;//顺序表当前长度
  7. }SqList;//顺序表类型定义
  8. void ListInsert(SqList &L,int i,int e)
  9. {
  10. for(int j=L.length;j>=i;j--)//将第i个元素及之后的元素后移
  11. L.data[j]=L.data[j-1];
  12. L.data[i-1]=e;
  13. //将需要插入的元素赋值e,因为数组从L.data[0]开始,所以这里第i个元素是[i-1]表示的
  14. L.length++;
  15. }
  16. int main()
  17. {
  18. SqList L;//声明一个顺序表
  19. InitList(L);
  20. ListInsert(L,3,3);//在三个位置插入数据元素3
  21. }

 如下图所示,表示ListInsert(L,3,3)

 若执行ListInsert(L,9,3),则会产生如下现象

 中间的值data[6],data[7]空了,而在顺序表中元素应该相邻存放,说明这段代码不够健壮,应该做如下调整

  1. bool ListInsert(SqList &L,int i,int e)
  2. {
  3. if(i<1||i>L.length+1)//判断i的范围是否有效
  4. return false;
  5. if(L.length>=MaxSize)//判断当前存储空间是否已满
  6. return false;
  7. for(int j=L.length;j>=i;j--)
  8. {
  9. L.data[j]=L.data[j-1];
  10. }
  11. L.data[i-1]=e;
  12. L.length++;
  13. return true;
  14. }

总的代码为

  1. #include <stdio.h>
  2. #define MaxSize 10 // 定义最大长度
  3. typedef int ElemType; // 假设 ElemType 为 int 类型
  4. typedef struct
  5. {
  6. ElemType data[MaxSize];
  7. int length; // 顺序表当前长度
  8. } SqList; // 顺序表类型定义
  9. void InitList(SqList& L)
  10. {
  11. L.length = 0; // 初始化顺序表长度为0
  12. }
  13. bool ListInsert(SqList& L, int i, ElemType e)
  14. {
  15. if (i < 1 || i > L.length + 1 || L.length >= MaxSize)
  16. {
  17. return false; // 插入位置不合法或顺序表已满,返回错误
  18. }
  19. for (int j = L.length; j >= i; j--)
  20. {
  21. L.data[j] = L.data[j - 1]; // 将第i个元素及之后的元素后移
  22. }
  23. L.data[i - 1] = e; // 将需要插入的元素赋值给e
  24. L.length++; // 顺序表长度加1
  25. return true;
  26. }
  27. int main()
  28. {
  29. SqList L; // 声明一个顺序表
  30. InitList(L); // 初始化顺序表
  31. ListInsert(L, 3, 3); // 在三个位置插入数据元素3
  32. return 0;
  33. }
2.插入操作的时间复杂度

最好情况:新元素插入到表尾,不需要移动元素
i= n+1,循环0次;最好时间复杂度=O(1);

最坏情况:新元素插入到表头,需要将原有的n个元素全都向后移动

i= 1,循环 n 次;最坏时间复杂度O(n);

平均情况:假设新元素插入到任何一个位置的概率相同,即i= 1,2,3,...,length+1 的概率都是 p=1/n+1,i= 1,循环 n 次;i=2 ,循环 n-1,i+3,循环n-2次,.....i=n+1时,循环0次
平均循环次数 =np +(n-1)p +(n-2)p + 1*p=(n(n+1)/2)*(1/n+1)=n/2

三.顺序表的删除操作

1.顺序表的删除
  1. bool ListDelete(SqList &L,int i,int &e)
  2. {
  3. if(i<1||i>L.length)
  4. return false;
  5. e=L.data[i-1];
  6. for(int j=i;j<L.length;j++)
  7. {
  8. L.data[j-1]=L.data[j];
  9. }
  10. L.length--;
  11. return true;
  12. }
  13. int main()
  14. {
  15. SqList L;
  16. InitList(L);
  17. int e=-1;
  18. if(ListDelete(L,3,e))
  19. printf("已删除第3个元素,删除元素值为=%d\n",e);
  20. else
  21. printf("位序i不合法,删除失败\n");
  22. return 0;
  23. }

插入

for(int j=L.length;j>=i;j--)//从后到前依次往后挪

删除

for(int j=i;j<L.length;j++)//从前到后依次往前挪

 2.删除操作的时间复杂度

最好情况:删除表尾元素,不需要移动其他元素
i= n,循环 0 次;最好时间复杂度 = O(1)

最坏情况:删除表头元素,需要将后续的 n-1 个元素全都向前移动

i= 1,循环 n-1 次;最坏时间复杂度 = O(n);

平均情况:假设删除任何一个元素的概率相同,即i= 1,2,3,...,length 的概率都是 p=1/n

平均循环次数 =(n-1)p +(n-2)p + 1*p=(n(n-1)/2)*(1/n)=n-1/2

四.顺序表的查找

1.按位查找操作:查找第i位置的元素
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define InitSize 10 // 顺序表的初始长度
  4. typedef struct
  5. {
  6. int* data; // 指示动态分配数组的指针
  7. int MaxSize;
  8. int length;
  9. } SeqList;
  10. void InitList(SeqList& L)
  11. {
  12. L.data = (int*)malloc(InitSize * sizeof(int));
  13. if (L.data == NULL)
  14. {
  15. // 内存分配失败的处理逻辑
  16. printf("内存分配失败\n");
  17. exit(1);
  18. }
  19. L.length = 0; // 初始时顺序表中没有元素
  20. L.MaxSize = InitSize;
  21. }
  22. int GetElem(SeqList L, int i)
  23. {
  24. if (i < 1 || i > L.length)
  25. {
  26. // 位置不合法,返回错误
  27. printf("位置不合法\n");
  28. exit(1);
  29. }
  30. return L.data[i - 1];
  31. }
  32. int main()
  33. {
  34. SeqList L;
  35. InitList(L);
  36. L.length=10;
  37. for (int i = 0; i < L.MaxSize; i++)
  38. L.data[i] = i;
  39. int a;
  40. printf("请输入您要查找的位置: ");
  41. scanf("%d", &a);
  42. printf("第%d个元素是%d\n", a, GetElem(L, a));
  43. free(L.data); // 释放动态分配的内存
  44. return 0;
  45. }
2.按位查找操作的时间复杂度:O(1)

3.按值查找操作
  1. #define InitSize 10
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. typedef struct {
  5. int* data;
  6. int MaxSize;
  7. int length;
  8. } SeqList;
  9. void InitList(SeqList& L)
  10. {
  11. L.data = (int*)malloc(InitSize * sizeof(int));
  12. L.length = 0;
  13. L.MaxSize = InitSize;
  14. }
  15. // 在顺序表L中查找第一个元素值等于e的元素,并返回其位序
  16. int LocateElem(SeqList L, int e)
  17. {
  18. for (int i = 0; i < L.length; i++)
  19. {
  20. if (L.data[i] == e)
  21. return i + 1; // 数组下标为i的元素值等于e,返回其位序为i+1
  22. }
  23. return 0; // 未找到该元素,返回0
  24. }
  25. int main()
  26. {
  27. SeqList L;
  28. InitList(L);
  29. L.length = 10;
  30. for (int i = 0; i < L.length; i++)
  31. {
  32. L.data[i] = i; // 给顺序表赋值
  33. }
  34. int e = 9;
  35. int a = LocateElem(L, 9); // 在顺序表L中查找元素9
  36. if (a != 0)
  37. {
  38. printf("该值位于%d\n", a); // 找到该值,输出它的位序
  39. }
  40. else
  41. {
  42. printf("未找到该值!\n"); // 未找到该值,输出提示信息
  43. }
  44. free(L.data); // 释放动态分配的内存
  45. return 0;
  46. }

4.按值查找的时间复杂度

最好情况:目标元素在表头
循环1次;最好时间复杂度 = O(1)

最坏情况:目标元素在表尾

循环 n 次;最坏时间复杂度 = O(n);
平均情况:假设目标元素出现在任何一个位置的概率相同,都是1/n
目标元素在第1位,循环1次;在第2位,循环2次;在第 n位,循环 n 次...... ;
平均循环次数 =1*1/n +1/n*2 +1/n*3 + =(n(n+1)/2)*(1/n)=n+1/2

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/922178
推荐阅读
相关标签
  

闽ICP备14008679号