【数据结构和算法】实现线性表中的静态、动态顺序表(下)

简介: 【数据结构和算法】实现线性表中的静态、动态顺序表(下)

五、完整代码演示

1.静态顺序表

所谓静态,就是指,不能更改顺序表最大存储元素个数,可能剩下很多,也可能不够

1.test.c

主函数的使用

#define _CRT_SECURE_NO_WARNINGS
#include"Seqtable.h"
//实现顺序表
void test1()
{
  Seqtable st;
  InitSeqtable(&st);//初始化
  //尾插
  BackSeqtable(&st, 1);
  BackSeqtable(&st, 2);
  BackSeqtable(&st, 3);
  BackSeqtable(&st, 4);
  BackSeqtable(&st, 5);
  //打印
  PrintSeqtable(&st);
  printf("\n");
  //头插
  FrontSeqtable(&st, 1);
  FrontSeqtable(&st, 2);
  FrontSeqtable(&st, 3);
  FrontSeqtable(&st, 4);
  FrontSeqtable(&st, 5);
  PrintSeqtable(&st);
  //尾巴删除
  SeqtablePopBack(&st);
  SeqtablePopBack(&st);
  SeqtablePopBack(&st);
  SeqtablePopBack(&st);
  SeqtablePopBack(&st);
  printf("\n");
  //打印
  PrintSeqtable(&st);
  //头删除
  SeqtablePopFront(&st);
  printf("\n");
  //打印
  PrintSeqtable(&st);
  摧毁顺序表
  //SeqtableDestory(&st);
  printf("\n");
  //打印
  ChangeSeqtable(&st);
  PrintSeqtable(&st);
}
int main()
{ //实现静态顺序表
  test1();
  return 0;
}

2.Seqtable.h

头文件的使用

#define _CRT_SECURE_NO_WARNINGS
//头文件,进行函数的声明
//    结构体的实现
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
#define MAX 100
//静态顺序表的实现
typedef struct Seqtable {
  int date[MAX];//数据域
  int size;//数据个数
}Seqtable;
//实现函数声明
//初始化函数
void InitSeqtable(Seqtable* st);
//尾插入
void BackSeqtable(Seqtable* st, int data);
//头插入
void FrontSeqtable(Seqtable* st, int data);
//尾删除
void SeqtablePopBack(Seqtable* st);
//头删除
void SeqtablePopFront(Seqtable* st);
//摧毁顺序表
void SeqtableDestory(Seqtable* st);
//打印
void PrintSeqtable(Seqtable* st);
//查找指定元素
//有 返回 下标
//没有 返回 -1
int SearchSeqtable(Seqtable* st);
//更改数据
void ChangeSeqtable(Seqtable* st);

3.Seqtable.c

函数的实现

#define _CRT_SECURE_NO_WARNINGS
#include"Seqtable.h"
//实现方法
//顺序表的,头插尾插,头删尾删
//初始化,和销毁
//静态顺序表
//初始化函数
void InitSeqtable(Seqtable* st) {
  for (int i = 0; i < MAX; i++) {
    st->date[i] = 0;//初始化为0  实际上可以不用初始化数组
  }
  st->size = 0;
}
//尾插入
void BackSeqtable(Seqtable* st, int data) {
  //尾部插入的时候要进行判别是否为满
  if (st->size == MAX) {
    //表示满了
    perror("顺序表已经满员,无法插入新数据\n");
    exit(-1);//退出就可以
  }
  //没有满员,就加入数据即可
  st->date[st->size++] = data;
}
//头插入
void FrontSeqtable(Seqtable* st, int data) {
  //一样先进行判断是否满员
  if (st->size == MAX) {
    perror("满员无法插入");
    exit(-1);
  }
  //头部插入。就是将原有数据向后移动一个位置
  int num = st->size - 1;
  for (int i = num; i>=0; i--) {
    st->date[i + 1] = st->date[i];
  }
  //while (num>=0) {
  //  st->date[num + 1] = st->date[num];
  //  num--;
  //}
  //最后插入数据
  st->date[0] = data;
  st->size++;
}
//尾删除
void SeqtablePopBack(Seqtable* st) {
  //尾删除,需要判断是否为空
  assert(st->size > 0);//断言判断
  st->size--;//直接元素个数减去一个就可以
}
//头删除
void SeqtablePopFront(Seqtable* st) {
  //头部删除,也要判空
  assert(st->size > 0);//断言
  //将后面的数据覆盖前面的数据
  for (int i = 0; i < st->size-1; i++) {
    st->date[i] = st->date[i + 1];
  }
  st->size--;//size减去一个元素即可
}
//摧毁顺序表
void SeqtableDestory(Seqtable* st) {
  //摧毁的话,静态表直接初始化为0
  st->size = 0;
}
//打印
void PrintSeqtable(Seqtable* st) {
  for (int i = 0; i < st->size; i++) {
    printf("%d ", st->date[i]);
  }
}
//查找
int SearchSeqtable(Seqtable* st) {
  assert(st->size > 0);//如果为空,不用查找,直接报错
  int num = 0;
  scanf("%d", &num);//输入查找的元素
  for (int i = 0; i < st->size; i++) {
    if (st->date[i] == num) {
      return i;//找到返回下标
    }
  }
  return -1;//没找到返回-1
}
void ChangeSeqtable(Seqtable* st) {
  int num=SearchSeqtable(st);//进入查找,返回下标
  if (num == -1) {
    printf("顺序表中没有该元素,无法修改\n");
    return;
  }
  int a = 0;
  scanf("%d", &a);//输入想要更改的数据
  st->date[num] = a;
}

2.动态顺序表

所谓动态,就是使用realloc等函数,动态开辟空间,尽量使得顺序表的空间合理化使用

1.test.c

主函数进行测试和使用顺序表

#define _CRT_SECURE_NO_WARNINGS
#include"动态顺序表.h"
void test2() {
  Seqtable st;
  InitSeqtable(&st);//初始化
  //尾插
  BackSeqtable(&st, 1);
  BackSeqtable(&st, 2);
  BackSeqtable(&st, 3);
  BackSeqtable(&st, 4);
  BackSeqtable(&st, 5);
  //打印
  PrintSeqtable(&st);
  printf("\n");
  //头插
  FrontSeqtable(&st, 1);
  FrontSeqtable(&st, 2);
  FrontSeqtable(&st, 3);
  FrontSeqtable(&st, 4);
  FrontSeqtable(&st, 5);
  PrintSeqtable(&st);
  //尾巴删除
  SeqtablePopBack(&st);
  SeqtablePopBack(&st);
  SeqtablePopBack(&st);
  SeqtablePopBack(&st);
  SeqtablePopBack(&st);
  printf("\n");
  //打印
  PrintSeqtable(&st);
  //头删除
  SeqtablePopFront(&st);
  printf("\n");
  //打印
  PrintSeqtable(&st);
  摧毁顺序表
  SeqListDestory(&st);
  //printf("\n");
  打印
  //PrintSeqtable(&st);
}
int main()
{
  test2();
  return 0;
}

2.Seqtable.h

函数声明和结构体创建

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
//动态顺序表
typedef struct Seqtable {
  int* data;//数据域
  int size;//个数
  int capacity;//容量
}Seqtable;
//实际上动态顺序表和静态顺序表,只有在初始化、销毁、扩容的时候不一样
//实现函数声明
//初始化函数
void InitSeqtable(Seqtable* st);
//尾插入
void BackSeqtable(Seqtable* st, int data);
//头插入
void FrontSeqtable(Seqtable* st, int data);
//尾删除
void SeqtablePopBack(Seqtable* st);
//头删除
void SeqtablePopFront(Seqtable* st);
//摧毁顺序表
void SeqtableDestory(Seqtable* st);
//打印
void PrintSeqtable(Seqtable* st);
//查找
int SearchSeqtable(Seqtable* st);
//更改
void ChangeSeqtable(Seqtable* st);

3.Seqtable.c

代码实现:

#define _CRT_SECURE_NO_WARNINGS
#include"动态顺序表.h"
//动态顺序表
//初始化顺序表
void InitSeqtable(Seqtable* st) {
  st->size = st->capacity = 0;
  st->data = NULL;
}
//扩容
void Expansion(Seqtable* st) {
  //1.直接扩容二倍,这样防止后序一致扩容
  int newcapacity = st->capacity = 0 ? 4 : st->capacity * 2;
  int* tmp = (int*)realloc(st->data, newcapacity * sizeof(int));
  if (tmp == NULL) {
    //表示创建失败
    perror("realloc fail\n");
    exit(-1);
  }
  //创建成功  tmp给data
  st->data = tmp;
  st->capacity = newcapacity;
}
//尾插入
void BackSeqtable(Seqtable* st, int data) {
  //判断是否满员
  if (st->size == st->capacity) {
    //满员进行扩容
    //两个方法
    //1.直接扩容二倍,这样防止后序一致扩容
    Expansion(st);
  }
  //如果没有满员,就正常使用
  st->data[st->size++] = data;
}
//头插入
void FrontSeqtable(Seqtable* st, int data) {
  //使用动态的
  if (st->size == st->capacity) {
    Expansion(st);
  }
  int end = st->size - 1;
  while (end >= 0) {
    st->data[end + 1] = st->data[end];
    --end;
  }
  st->data[0] = data;
  st->size++;
}
//尾删除
void SeqtablePopBack(Seqtable* st) {
  //尾删除,需要判断是否为空
  assert(st->size > 0);//断言判断
  st->size--;//直接元素个数减去一个就可以
}
//头删除
void SeqtablePopFront(Seqtable* st) {
  //头部删除,也要判空
  assert(st->size > 0);//断言
  //将后面的数据覆盖前面的数据
  for (int i = 0; i < st->size - 1; i++) {
    st->data[i] = st->data[i + 1];
  }
  st->size--;//size减去一个元素即可
}
//打印
void PrintSeqtable(Seqtable* st) {
  for (int i = 0; i < st->size; i++) {
    printf("%d ", st->data[i]);
  }
}
//摧毁动态顺序表
//void SeqtableDestory(Seqtable* st) {
//  //先释放空间
//  free(st->data);
//  st->data = NULL;
//  free(st);
//  st->size = st->capacity = 0;
//}
void SeqListDestory(Seqtable* ps) {
  free(ps->data);//直接释放a的空间 
  ps->data = NULL;//然后指向NULL
  ps->capacity = ps->size = 0;
}
//查找
int SearchSeqtable(Seqtable* st) {
  assert(st->size > 0);//如果为空,不用查找,直接报错
  int num = 0;
  scanf("%d", &num);//输入查找的元素
  for (int i = 0; i < st->size; i++) {
    if (st->data[i] == num) {
      return i;//找到返回下标
    }
  }
  return -1;//没找到返回-1
}
void ChangeSeqtable(Seqtable* st) {
  int num = SearchSeqtable(st);//进入查找,返回下标
  if (num == -1) {
    printf("顺序表中没有该元素,无法修改\n");
    return;
  }
  int a = 0;
  scanf("%d", &a);//输入想要更改的数据
  st->data[num] = a;
}

总结

我们本文讲解了,线性表中的顺序表的使用,我们分别实现了静态和动态的顺序表,这是数据结构的基础,我们接下来讲解的内容是线性表中的链表。

好了,行文至此,感谢这一段时间来大家的鼓励和支持,小王会继续努力学习代码的,一起加油啊!!!

相关文章
|
10月前
|
机器学习/深度学习 传感器 算法
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
635 2
|
11月前
|
机器学习/深度学习 人工智能 算法
【多智能体编队】基于自适应控制算法非线性输入的多智能体系统编队控制研究(Matlab代码复现)
【多智能体编队】基于自适应控制算法非线性输入的多智能体系统编队控制研究(Matlab代码复现)
266 0
|
11月前
|
传感器 算法 Python
【电机矢量控制算法】基于线性死区补偿的永磁同步电机矢量控制算法仿真
【电机矢量控制算法】基于线性死区补偿的永磁同步电机矢量控制算法仿真
305 3
|
11月前
|
机器学习/深度学习 算法 数据格式
MARS算法理论和Python代码实现:用分段回归解决非线性时间序列预测问题
本文将深入探讨MARS算法的核心原理,并详细阐述其在时间序列预测任务中的应用策略与技术实现。
548 0
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
773 1
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
304 0
|
算法 Java
算法系列之数据结构-Huffman树
Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
489 3
 算法系列之数据结构-Huffman树
|
算法 Java
算法系列之数据结构-二叉搜索树
二叉查找树(Binary Search Tree,简称BST)是一种常用的数据结构,它能够高效地进行查找、插入和删除操作。二叉查找树的特点是,对于树中的每个节点,其左子树中的所有节点都小于该节点,而右子树中的所有节点都大于该节点。
661 22
232.用栈实现队列,225. 用队列实现栈
在232题中,通过两个栈(`stIn`和`stOut`)模拟队列的先入先出(FIFO)行为。`push`操作将元素压入`stIn`,`pop`和`peek`操作则通过将`stIn`的元素转移到`stOut`来实现队列的顺序访问。 225题则是利用单个队列(`que`)模拟栈的后入先出(LIFO)特性。通过多次调整队列头部元素的位置,确保弹出顺序符合栈的要求。`top`操作直接返回队列尾部元素,`empty`判断队列是否为空。 两题均仅使用基础数据结构操作,展示了栈与队列之间的转换逻辑。
|
编译器 C语言 C++
栈区的非法访问导致的死循环(x64)
这段内容主要分析了一段C语言代码在VS2022中形成死循环的原因,涉及栈区内存布局和数组越界问题。代码中`arr[15]`越界访问,修改了变量`i`的值,导致`for`循环条件始终为真,形成死循环。原因是VS2022栈区从低地址到高地址分配内存,`arr`数组与`i`相邻,`arr[15]`恰好覆盖`i`的地址。而在VS2019中,栈区先分配高地址再分配低地址,因此相同代码表现不同。这说明编译器对栈区内存分配顺序的实现差异会导致程序行为不一致,需避免数组越界以确保代码健壮性。
287 0
栈区的非法访问导致的死循环(x64)

热门文章

最新文章