数据结构与算法——顺序表

简介: 数据结构与算📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段和数据结构阶段>——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的📖作者主页:热爱编程的小K📖专栏链接:数据结构🎉欢迎各位→点赞👏 + 收藏💞 + 留言🔔​💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🐾今日好句:世事洞明皆学问,人情练达即文章————————————————版权声明:本文为CSDN博主「热爱编程的小K」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声法——顺序表

e9301c5f69584abeba1e0fb445e113bf.png

75014fb71b9241a59da7d42093b2c55e.png

目录

顺序表概念

顺序表有三种写法


时间不浪费,空间无所谓:直接定义一个足够大的数组


空间不浪费,时间无所谓:采用动态数组,用一个开一个


时间空间均衡:也就是所谓的扩容


每次申请内存是之前内存的1.5倍(如果n的0.5倍小于或者等于1),那么是当前元素个数加一


不超过0.5倍数据量的空间浪费换取超过0.5倍数据量的时间节约

1.准备

包含一下用到的头文件,准备一个数据结构体

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<assert.h>

typedef struct student

{

char name[20];

int age;

double score;

}stu;

int curSize;        //记录当前元素个数

int capacity;       //记录当前容量

stu* pArr;          //指向当前内存段的首地址

2.初始化

把里面的值初始化为0,指针初始化为空

void initData()

{

curSize = 0;

capacity = 0;

pArr = NULL;

}

3.插入数据

插入数据就不多说了,详解代码在下面,这里主要图解一下扩容问题

b8cced30b7db44ad88a9109a479f8efb.png

void pushData(stu* inserData)

{

//需要开内存

if (capacity <= curSize)  

{

 //计算新开内存

       //右移一位相当于除以2

 capacity += (capacity >> 1 > 1) ? (capacity >> 1) : 1;

 stu* pNew = (stu*)malloc(sizeof(stu) * capacity);//新开内存

 assert(pNew);     //防御性编程

 if (pArr)

 {

           //把pArr中的数据拷贝到新开内存段中

  memcpy(pNew, pArr, sizeof(stu) * curSize);

  //释放原有内存段

  free(pArr);

 }

 //pArr指向新开内存段

 pArr = pNew;

}

//inserData放入数组中

memcpy(pArr + curSize, inserData, sizeof(stu));

//元素个数加一

curSize++;

}

4.浏览数据

遍历数据,显示出容量和当前元素的比,可轻易看出空间利用率

void watchData()

{

printf("pArr[%d][%d]:\n", curSize,capacity);

for (int i = 0; i < curSize; i++)

{

 printf("%s-%d-%.2f\n",  

  pArr[i].name, pArr[i].age, (pArr+i)->score);

       //两种写法,自由变换

}

printf("\n");

}

5.查找数据

简单的查找程序,找到了返回该位置的下标

int findData(stu* findData)

{

for (int i = 0; i < curSize; i++)

{

 if (

  0 == strcmp((pArr+i)->name,findData->name)

  && pArr[i].age == findData->age  

  && pArr[i].score == findData->score

  )

 {

  return i;

 }

}

return -1;

}

6.删除数据

这里是牺牲了一部分空间,来获得时间效率的提高

90081fdd898b4b45a197447617e9a871.png

void delData(stu* delData)

{

int index = findData(delData);

//找到了

if (index != -1)

{

 if(curSize == 1)    //只有一个元素时

 {

  free(pArr);

  initData();

 }

 else

 {

  //申请新空间

  stu* pNew = (stu*)malloc(sizeof(stu) * (curSize - 1));

  assert(pNew);

  if (index != 0)

  {

   //该元素前面有元素,把前面元素拷贝到新内存段

   memcpy(pNew, pArr, sizeof(stu) * index);

  }

  if (index != curSize - 1)

  {

   //该元素后面又元素,把后面元素拷贝到新内存段

   memcpy(pNew + index, pArr + index + 1,  

                      sizeof(stu) * (curSize - 1 - index));

  }

  free(pArr);        //释放原来的空间

  pArr = pNew;       //pArr指向新数据

  curSize--;

  capacity = curSize;

 }

}

else

{

 printf("没找到,删除失败!\n");

}

}

7.修改数据

这里主要是利用了查找函数的特性来完成

void modify(stu* srcData, stu* dscData)

{

int index = findData(srcData);

if (index != -1)

{

 memcpy(pArr + index, dscData, sizeof(stu));

}

else

{

 printf("修改失败,没找到\n");

}

}

8.综合代码

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<assert.h>

typedef struct student

{

char name[20];

int age;

double score;

}stu;

int curSize;        //记录当前元素个数

int capacity;       //记录当前容量

stu* pArr;          //指向当前内存段的首地址

//初始化

void initData();

//insertData

void pushData(stu* inserData);

//浏览数据

void watchData();

//查找数据

int findData(stu* findData);

//删除数据

void delData(stu* delData);

//修改数据

void modify(stu* srcData, stu* dscData);

int main()

{

initData();

stu d[5] =  

{

 { "关羽", 18, 18.67 },

 { "张飞", 28, 28.67 },

 { "赵云", 38, 38.67 },

 { "马超", 48, 58.67 },

 { "黄忠", 58, 48.67 }

};

for (int i = 0; i < 5; i++)

{

 pushData(d + i);

}

watchData();

delData(d+2);

watchData();

modify(d, d + 1);

watchData();

return 0;

}

//初始化

void initData()

{

curSize = 0;

capacity = 0;

pArr = NULL;

}

//insertData

void pushData(stu* inserData)

{

//需要开内存

if (capacity <= curSize)  

{

 //计算新开内存

 capacity += (capacity >> 1 > 1) ? (capacity >> 1) : 1;

 stu* pNew = (stu*)malloc(sizeof(stu) * capacity);//新开内存

 assert(pNew);     //防御性编程

 if (pArr)

 {

  memcpy(pNew, pArr, sizeof(stu) * curSize);

  //释放原有内存段

  free(pArr);

 }

 //pArr指向新开内存段

 pArr = pNew;

}

//inserData放入数组中

memcpy(pArr + curSize, inserData, sizeof(stu));

//元素个数加一

curSize++;

}

//浏览数据

void watchData()

{

printf("pArr[%d][%d]:\n", curSize,capacity);

for (int i = 0; i < curSize; i++)

{

 printf("%s-%d-%.2f\n",  

  pArr[i].name, pArr[i].age, (pArr+i)->score);

}

printf("\n");

}

//查找数据

int findData(stu* findData)

{

for (int i = 0; i < curSize; i++)

{

 if (

  0 == strcmp((pArr+i)->name,findData->name)

  && pArr[i].age == findData->age  

  && pArr[i].score == findData->score

  )

 {

  return i;

 }

}

return -1;

}

//删除数据

void delData(stu* delData)

{

int index = findData(delData);

//找到了

if (index != -1)

{

 if(curSize == 1)    //只有一个元素时

 {

  free(pArr);

  initData();

 }

 else

 {

  //申请新空间

  stu* pNew = (stu*)malloc(sizeof(stu) * (curSize - 1));

  assert(pNew);

  if (index != 0)

  {

   //该元素前面有元素,把前面元素拷贝到新内存段

   memcpy(pNew, pArr, sizeof(stu) * index);

  }

  if (index != curSize - 1)

  {

   //该元素后面又元素,把后面元素拷贝到新内存段

   memcpy(pNew + index, pArr + index + 1, sizeof(stu) * (curSize - 1 - index));

  }

  free(pArr);      //释放原来的空间

  pArr = pNew;       //pArr指向新数据

  curSize--;

  capacity = curSize;

 }

}

else

{

 printf("没找到,删除失败!\n");

}

}

//修改数据

void modify(stu* srcData, stu* dscData)

{

int index = findData(srcData);

if (index != -1)

{

 memcpy(pArr + index, dscData, sizeof(stu));

}

else

{

 printf("修改失败,没找到\n");

}

}

9.测试案例

下面是我的测试案例的输出结果26a568bd2f4e4eddab3990db9a1c9dc6.png———————————

版权声明:本文为CSDN博主「热爱编程的小K」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_72157449/article/details/128743508

相关文章
|
1月前
|
存储 编译器 C语言
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
52 2
|
25天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
25天前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
56 3
|
25天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
1月前
|
存储 Java
数据结构第二篇【关于java线性表(顺序表)的基本操作】
数据结构第二篇【关于java线性表(顺序表)的基本操作】
31 6
|
1月前
|
存储 安全 Java
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
25 3
|
1月前
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
21 2
|
1月前
|
存储 算法 索引
【数据结构】——顺序表
【数据结构】——顺序表
|
1月前
|
存储
【数据结构】线性表和顺序表
【数据结构】线性表和顺序表
22 1
|
1月前
|
存储
数据结构1——顺序表
数据结构1——顺序表
17 1
下一篇
无影云桌面