C语言《数据结构》——顺序表的增,删,查,改。

简介: C语言《数据结构》——顺序表的增,删,查,改。

前言


顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。


提示:以下是本篇文章正文内容,下面案例可供参考


一、顺序表的相关描述


5fcd0b5b7b9550892b6fc1066836c6bd_watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5b-D6ZqP6ICM5Yqo,size_20,color_FFFFFF,t_70,g_se,x_16.png


二、顺序表的增删查改;


1.定义顺序表


代码如下(示例):


typedef struct
{
  tempstyle* data;
  //数据域;
  int curpity;
  //链表的容量;
  int cursize;
  //链表的长度; 
}Seqlist;


2.顺序表的初始化


代码如下(示例):


Seqlist* INIT_list(Seqlist* plist)//顺序表初始化; 
{
  //对链表的容量进行赋值;
  plist->curpity = SEQ_INIT_SIZE;
  plist->cursize = 0;
  plist->data = (tempstyle*)malloc(sizeof(tempstyle) * plist->curpity);
  //申请动态存储空间; 
}


3.顺序表查找,删除,插入;


顺序表本质就是一定长度的具有连续地址的数组,所以数据的查询和删除都是在数组的基础上进行,考察的就是数组的应用。


bool insert_list(Seqlist* plist, int pos, tempstyle val)
{
  assert(plist != NULL);
  if (pos<0 || pos>plist->cursize)
  {
  return false;
  }
  if (INIT_man(plist) == true)
  {
  return false;
  }
  else
  {
  for (int i = plist->cursize; i > pos; i--)
  {
    plist->data[i] = plist->data[i - 1];
  }
  plist->data[pos] = val;
  plist->cursize += 1;
  return true;
  /*
  for(int i=plist->cursize-1;i>=pos;i--)
  {
    plist->data[i+1]=plist->data[i];
  }
  plist->data[pos]=val;
  plist->cursize+=1;
  return true;
  */
  }
}
//查找函数,对输入的值进行查找;
int FIND_list(Seqlist* plist, tempstyle val)
{
  assert(plist != NULL);
  int pos = plist->cursize;
  while (pos > 0 && plist->data[pos - 1] != val)
  {
  pos--;
  }
  if (pos == 0)
  return -1;
  else
  return pos;
}


4.顺序表的扩容;


顺序表的扩容就是将已有的数据转移到另一个大一点的数组中。可以用realloc函数,也可以用memmove函数,也可以用数组直接单个单个进行转移。以上三种方法我都已经实现。可以自己测试。
bool INIT_seqlist(Seqlist* plist)
{
  assert(plist != NULL);
  int total;
  total = plist->curpity * SEQ_SIZE;
  tempstyle* newnode = (tempstyle*)malloc(sizeof(tempstyle) * total);
  if (plist == NULL)
  {
  return false;
  }
  else
  {
  /*  for(int i=0;i<plist->curpity;i++)
    {
    newnode[i]=plist->data[i];
    }
    memmove(newnode,plist->data,sizeof(tempstyle)*plist->curpity);
    free(plist->data);
    plist->data=newnode;
    plist->curpity=total;
    return true;*/
  plist->data = (tempstyle*)realloc(plist->data, sizeof(tempstyle) * total);//增加到tatol的空间; 
  plist->cursize += 1;
  plist->curpity = total;
  return true;
  }
}


三、顺序表的源代码;


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>  //printf
#include<stdlib.h>  //malloc,realloc,free
#include<assert.h>//assert
#include<string.h>//memmove内存移动函数, 
//#define NDEBUG  //可以对assert函数进行禁用; 
#define SEQ_INIT_SIZE 10
#define SEQ_SIZE 2
typedef int tempstyle;
typedef struct
{
  tempstyle* data;
  //数据域;
  int curpity;
  //链表的容量;
  int cursize;
  //链表的长度; 
}Seqlist;
//功能模块化;
//对链表进行动态空间的申请; 
Seqlist* INIT_list(Seqlist* plist)//顺序表初始化; 
{
  //对链表的容量进行赋值;
  plist->curpity = SEQ_INIT_SIZE;
  plist->cursize = 0;
  plist->data = (tempstyle*)malloc(sizeof(tempstyle) * plist->curpity);
  //申请动态存储空间; 
}
//创建链表; 
void creatlist(Seqlist* plist, int n)
{
  assert(plist != NULL);
  plist->cursize = n;
  for (int i = 0; i < n; i++)
  {
  scanf("%d", &plist->data[i]);
  }
}
//创建打印函数;
void printlist(Seqlist* plist)
{
  assert(plist != NULL);
  printf("输出链表:\n");
  for (int i = 0; i < plist->cursize; i++)
  {
  printf("%5d", plist->data[i]);
  }
  putchar('\n');
}
//判断是否已经满了;
bool INIT_man(const Seqlist* plist)
{
  assert(plist != NULL);
  if (plist->cursize < plist->curpity)
  {
  return false;
  }
  else
  return true;
}
//创建插入函数;
bool insert_list(Seqlist* plist, int pos, tempstyle val)
{
  assert(plist != NULL);
  if (pos<0 || pos>plist->cursize)
  {
  return false;
  }
  if (INIT_man(plist) == true)
  {
  return false;
  }
  else
  {
  for (int i = plist->cursize; i > pos; i--)
  {
    plist->data[i] = plist->data[i - 1];
  }
  plist->data[pos] = val;
  plist->cursize += 1;
  return true;
  /*
  for(int i=plist->cursize-1;i>=pos;i--)
  {
    plist->data[i+1]=plist->data[i];
  }
  plist->data[pos]=val;
  plist->cursize+=1;
  return true;
  */
  }
}
//查找函数,对输入的值进行查找;
int FIND_list(Seqlist* plist, tempstyle val)
{
  assert(plist != NULL);
  int pos = plist->cursize;
  while (pos > 0 && plist->data[pos - 1] != val)
  {
  pos--;
  }
  if (pos == 0)
  return -1;
  else
  return pos;
}
//判断链表是否为空;
bool INIT_kong(const Seqlist* plist)
{
  assert(plist != NULL);
  if (plist->cursize == 0)
  return true;
  else
  return false;
}
//增加扩容;
bool INIT_seqlist(Seqlist* plist)
{
  assert(plist != NULL);
  int total;
  total = plist->curpity * SEQ_SIZE;
  tempstyle* newnode = (tempstyle*)malloc(sizeof(tempstyle) * total);
  if (plist == NULL)
  {
  return false;
  }
  else
  {
  /*  for(int i=0;i<plist->curpity;i++)
    {
    newnode[i]=plist->data[i];
    }
    memmove(newnode,plist->data,sizeof(tempstyle)*plist->curpity);
    free(plist->data);
    plist->data=newnode;
    plist->curpity=total;
    return true;*/
  plist->data = (tempstyle*)realloc(plist->data, sizeof(tempstyle) * total);//增加到tatol的空间; 
  plist->cursize += 1;
  plist->curpity = total;
  return true;
  }
}
//尾部插入;
void insert_back(Seqlist* plist, tempstyle val)
{
  assert(plist != NULL);
  //也可以调用函数,进行插入; 
  insert_list(plist, plist->cursize, val);
  /*
  plist->data[plist->cursize]=val;
  plist->cursize+=1;
  */
}
//头部插入; 
void insert_front(Seqlist* plist, tempstyle val)
{
  assert(plist != NULL);
  insert_list(plist, 0, val);
  /*
  for(int i=plist->cursize;i>0;i--)
  {
  plist->data[i]=plist->data[i-1];
  }
  plist->data[0]=val;
  plist->cursize+=1;
  */
}
void makemenu()
{
  printf("\t创建循环链表:\n");
  putchar('\n');
  printf("\t输入你要输入的值:\n");
  putchar('\n');
  printf("\tn代表链表的长度,val1代表头插入的值,val2代表尾插入的值:\n");
  putchar('\n');
  printf("\t你可以输入pos的值来删除函数中指定位置的数据:\n");
  putchar('\n');
}
//求出链表还差多少字节才能满;
int LENGTH_list(Seqlist* plist)
{
  assert(plist != NULL);
  if (plist->cursize == plist->curpity)
  {
  printf("链表已经满了:\n");
  }
  else
  return plist->curpity - plist->cursize;
}
int length_list(Seqlist* plist)
{
  assert(plist != NULL);
  return plist->cursize;
}
//指定位置删除; 
bool delete_list(Seqlist* plist, int pos)
{
  assert(plist != NULL);
  //需要判断输入的位置是否存在;
  if (pos > 0 && pos <= plist->cursize)
  {
  for (int i = pos - 1; i <= plist->cursize - 1; i++)
  {
    plist->data[i] = plist->data[i + 1];//最后一个给了空值; 
  }
  /*
  for(int i=pos;i<plist->cursize;i++)
  {
  plist->data[i-1]=plist->data[i];
  }
  */
  plist->cursize -= 1;
  return true;
  }
  else
  return false;
}
//判断一个值是否在这个表中;
bool ADJUST_list(Seqlist* plist, tempstyle val)
{
  assert(plist != NULL);
  int cnt = 0;
  for (int i = 0; i < plist->cursize; i++)
  {
  if (plist->data[i] == val)
  {
    cnt++;
  }
  }
  if (cnt >= 1)
  return true;
  else
  return false;
}
//删除你想删除的值;
int delete_val_list(Seqlist* plist, tempstyle val)//状态返回; 
{
  assert(plist != NULL);
  return  delete_list(plist, FIND_list(plist, val));
}
//摧毁函数;
void destroy_list(Seqlist* plist)
{
  plist->curpity = 0;
  plist->cursize = 0;
  free(plist->data);
}
//链表重置为空;
void clear_list(Seqlist* plist)
{
  assert(plist != NULL);
  plist->cursize = 0;
}
//删除链表中所有等于val的值;
/*void delete_all_list(Seqlist*plist,tempstyle val)
 {
  assert(plist!=NULL);
  int pos;
  while(pos=FIND_list(plist,val)!=-1)
  {
  delete_list(plist,pos);
  }
 }
 */
 /*void delete_all_list(Seqlist*plist,tempstyle val)
 {
  assert(plist!=NULL);
  int j=-1;
  int i=0;
  for(i;i<plist->cursize;++i)
  {
   if(plist->data[i]!=val)
   {
    j+=1;
    plist->data[j]=plist->data[i];
   }
  }
  plist->cursize=j+1;
 }*/
void delete_all_list(Seqlist* plist, tempstyle val)
{
  assert(plist != NULL);
  tempstyle* newnode = (tempstyle*)malloc(sizeof(tempstyle) * plist->curpity);
  int i = 0;
  for (int j = 0; j < plist->cursize; j++)
  {
  if (plist->data[j] != val)
  {
    newnode[i] = plist->data[j];
    i++;
  }
  }
  memmove(plist->data, newnode, i);
  plist->cursize = i;
}
//创建主函数; 
int main()
{
  Seqlist* plist;
  int n;
  int m;
  int pos;
  tempstyle val1, val2, val3;
  system("color 05");
  makemenu();
  scanf("%d", &n);
  INIT_list(plist);
  if (n > 10)
  {
  INIT_seqlist(plist);
  }
  creatlist(plist, n);
  printlist(plist);
  printf("\t输入你要插入的值:\n");
  scanf("%d", &val1);
  insert_front(plist, val1);
  printlist(plist);
  printf("\t输入你要插入的值:\n");
  scanf("%d", &val2);
  insert_back(plist, val2);
  printlist(plist);
  printf("链表的长度为:\n");
  printf("%d\n", length_list(plist));
  if (INIT_man(plist) == true)
  {
  printf("\t链表已经满了:\n");
  return 0;
  }
  if (INIT_kong(plist) == true)
  {
  printf("\t链表为空:\n");
  }
  m = LENGTH_list(plist);
  printf("\t链表还差%d才会满:\n", m);
  printf("\t判断链表中是否有你输入的值:\n");
  scanf("%d", &val3);
  if (ADJUST_list(plist, val3) == true)
  {
  printf("\t有你要查找的数:\n");
  }
  printf("\t现在可以进行删除函数:\n");
  printf("输入n你要删除的数据的位置:\n");
  scanf("%d", &pos);
  delete_list(plist, pos);
  printf("删除后的链表的长度为:\n");
  printf("%d", length_list(plist));
  printlist(plist);
  tempstyle val4;
  printf("\t删除链表中所有指定的值:\n");
  scanf("%d", &val4);
  delete_all_list(plist, val4);
  printlist(plist);
  putchar('\n');
  m = LENGTH_list(plist);
  printf("\t链表还差%d才会满:\n", m);
  //destroy_list(plist); 
  return 0;                                                                                                                                                                                                                                                                                                                                                                                                                               return 0;
}


总结


顺序表想比单链表有操作简单,无需更多的内存空间,查询数据简单。但是链表的长度不容易控制,每次插入数据需要移动大量数据,容易造成数据遗失。

相关文章
|
14天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
90 9
|
13天前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
56 16
|
13天前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
62 8
|
16天前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
44 4
|
17天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
17天前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
49 3
|
17天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
16天前
|
C语言
【数据结构】双向带头循环链表(c语言)(附源码)
本文介绍了双向带头循环链表的概念和实现。双向带头循环链表具有三个关键点:双向、带头和循环。与单链表相比,它的头插、尾插、头删、尾删等操作的时间复杂度均为O(1),提高了运行效率。文章详细讲解了链表的结构定义、方法声明和实现,包括创建新节点、初始化、打印、判断是否为空、插入和删除节点等操作。最后提供了完整的代码示例。
37 0
|
5天前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
14 1
|
8天前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。

热门文章

最新文章