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;
}


总结


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

相关文章
|
2月前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
66 1
|
2月前
|
存储 算法 搜索推荐
【趣学C语言和数据结构100例】91-95
本文涵盖多个经典算法问题的C语言实现,包括堆排序、归并排序、从长整型变量中提取偶数位数、工人信息排序及无向图是否为树的判断。通过这些问题,读者可以深入了解排序算法、数据处理方法和图论基础知识,提升编程能力和算法理解。
65 4
|
2月前
|
存储 机器学习/深度学习 搜索推荐
【趣学C语言和数据结构100例】86-90
本文介绍并用C语言实现了五种经典排序算法:直接插入排序、折半插入排序、冒泡排序、快速排序和简单选择排序。每种算法都有其特点和适用场景,如直接插入排序适合小规模或基本有序的数据,快速排序则适用于大规模数据集,具有较高的效率。通过学习这些算法,读者可以加深对数据结构和算法设计的理解,提升解决实际问题的能力。
53 4
|
2月前
|
存储 算法 数据处理
【趣学C语言和数据结构100例】81-85
本文介绍了五个经典算法问题及其C语言实现,涵盖图论与树结构的基础知识。包括使用BFS求解单源最短路径、统计有向图中入度或出度为0的点数、统计无向无权图各顶点的度、折半查找及二叉排序树的查找。这些算法不仅理论意义重大,且在实际应用中极为广泛,有助于提升编程能力和数据结构理解。
55 4
|
2月前
|
算法 数据可视化 数据建模
【趣学C语言和数据结构100例】76-80
本文介绍了五种图论算法的C语言实现,涵盖二叉树的层次遍历及广度优先搜索(BFS)和深度优先搜索(DFS)的邻接表与邻接矩阵实现。层次遍历使用队列按层访问二叉树节点;BFS利用队列从源节点逐层遍历图节点,适用于最短路径等问题;DFS通过递归或栈深入图的分支,适合拓扑排序等场景。这些算法是数据结构和算法学习的基础,对提升编程能力和解决实际问题至关重要。
57 4
|
2月前
|
存储 算法 vr&ar
【趣学C语言和数据结构100例】71-75
本文介绍了五个C语言数据结构问题及其实现,涵盖链表与二叉树操作,包括按奇偶分解链表、交换二叉树左右子树、查找节点的双亲节点、计算二叉树深度及求最大关键值。通过递归和遍历等方法,解决了理论与实际应用中的常见问题,有助于提升编程能力和数据结构理解。
50 4
|
2月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】66-70
本书《趣学C语言和数据结构100例》精选了5个典型的数据结构问题及C语言实现,涵盖链表与数组操作,如有序集合的集合运算、有序序列表的合并、数组中两顺序表位置互换、三递增序列公共元素查找及奇偶数重排。通过详细解析与代码示例,帮助读者深入理解数据结构与算法设计的核心思想,提升编程技能。
39 4
|
7天前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
本文档介绍了线性表的基本运算任务,涵盖顺序表和链表的初始化、销毁、判定是否为空、求长度、输出、查找元素、插入和删除元素等内容。通过C++代码示例详细展示了每一步骤的具体实现方法,并提供了测试说明和通关代码。 主要内容包括: - **任务描述**:实现顺序表的基本运算。 - **相关知识**:介绍线性表的基本概念及操作,如初始化、销毁、判定是否为空表等。 - **具体操作**:详述顺序表和链表的初始化、求长度、输出、查找、插入和删除元素的方法,并附有代码示例。 - **测试说明**:提供测试输入和预期输出,确保代码正确性。 - **通关代码**:给出完整的C++代码实现,帮助完成任务。 文档
24 5
|
21天前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
82 5

热门文章

最新文章