线性结构之顺序表(实现顺序表基本功能)

本文介绍了线性结构的特点,特别是线性表的内容。接着详细讲解了顺序表的概念,包括静态和动态顺序表,并列举了动态顺序表的基本操作,如初始化、插入、删除、查找等。通过创建SeqList.h和SeqList.c文件来实现这些操作,并通过主函数验证其正确性,初始容量设定为10。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、什么是线性结构?有什么特点?

线性结构是n个数据元素的有序集合。这个集合有以下特点:

1、集合中必存在唯一的一个"第一个元素";
2.集合中必存在唯一的一个"最后的元素";
3.除最后元素之外,其它数据元素均有唯一的"后继";
4.除第一元素之外,其它数据元素均有唯一的"前驱"。

数据结构中线性结构指的是数据元素之间存在着“一对一”的线性关系的数据结构。
如(a0,a1,a2,…,an),a0为第一个元素,an为最后一个元素,此集合即为一个线性结构的集合。
相对应于线性结构,非线性结构的逻辑特征是一个结点元素可能对应多个直接前驱和多个后继。

2、线性表中都包含什么内容?

线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串……

3、什么是顺序表?顺序表的分类?

顺序表使用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。

顺序表一般可分为:

  • 静态顺序表:使用定长数组存储。
  • 动态顺序表:使用动态开辟的数组存储。
4、完成动态顺序表的以下操作:

初始化、尾插、尾删、头插、头删、指定位置插入与删除、查找、检测顺序表是否为空、元素清空、扩容等。
首先建立一个SeqList.h头文件。

#pragma once
typedef int DataType;
typedef struct SeqList {
 DataType* _array;//指向动态开辟的数组
 int _capacity;//顺序表的总大小
 int _size;//顺序表中有效元素的个数
}SeqList, *PSeq;

//顺序表的初始化
void SeqListInit(PSeq ps, int capacity);

//在顺序表的尾部插入值为data的元素
void SeqListPushBack(PSeq ps, DataType data);

//删除顺序表最后一个元素
void SeqListPopBack(PSeq ps);

//在顺序表的头部插入值为data的元素
void SeqListPushFront(PSeq ps, DataType data);

//删除顺序表头部的元素
void SeqListPopFront(PSeq ps);

//在顺序表pos位置插入值为data的元素
void SeqListInsert(PSeq ps, int pos, DataType data);

//删除顺序表中pos位置的元素
void SeqListErase(PSeq ps, int pos);

//在顺序表中查找值为data的元素,找到返回该元素在顺序表中的下标,否则返回-1
int SeqListFind(PSeq ps, DataType data);

//检测顺序表是否为空,如果为空返回非零值,非空返回0
int SeqListEmpty(PSeq ps);

//返回顺序表中有效元素的个数
int SeqListSize(PSeq ps);

//返回顺序表的容量大小
int SeqListCapacity(PSeq ps);

//将顺序表中的元素清空
void SeqListClear(PSeq ps);

//删除顺序表中第一个值为data的元素
void SeqListRemove(PSeq ps, DataType data);

//销毁顺序表
void SeqListDestory(PSeq ps);

//顺序表的扩容
void CheckCapacity(PSeq ps);
void PrintSeqList(PSeq ps);

建立SeqList.c文件,来实现以上功能。

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <assert.h>
#include "test.h"

void SeqListInit(PSeq ps, int capacity) {//初始化顺序表
 ps->_size = 0;
 ps->_capacity = capacity;
 ps->_array = (DataType*)malloc(sizeof(DataType)*capacity);
 if (ps->_array == NULL) {
  assert(0);//借此来确定是空间申请失败的问题,方便下一步调试
  return;
 }
}

void SeqListPushBack(PSeq ps, DataType data) {//尾插
 assert(ps);
 CheckCapacity(ps);//检测顺序表是否满
 ps->_array[ps->_size] = data;
 ps->_size++;
}

void SeqListPopBack(PSeq ps) {//尾删
 assert(ps);
 if (SeqListEmpty(ps)) {//若顺序表为空,则直接返回
  return;
 }
 ps->_size--;
}

void SeqListPushFront(PSeq ps, DataType data) {//头插
 assert(ps);
 CheckCapacity(ps);
 for (int i = ps->_size; i > 0; --i) {//所有元素向后搬移一个位置
  ps->_array[i] = ps->_array[i - 1];
 }
 ps->_array[0] = data;
 ps->_size++;
}

void SeqListPopFront(PSeq ps) { //头删
 assert(ps);
 if (SeqListEmpty(ps)) {
  return;
 }
for (int i = 1; i < ps->_size; ++i) { //直接将后面元素向前搬移,覆盖掉首位元素
  ps->_array[i - 1] = ps->_array[i];
 }
 ps->_size--;
}

void SeqListInsert(PSeq ps, int pos, DataType data) {   //pos位置插入元素
 assert(ps);
 if (pos<0 || pos> ps->_size)
  return;
 CheckCapacity(ps);
 for (int i = ps->_size; i > pos; --i) {    //pos位置后的元素向后搬移一位
  ps->_array[i] = ps->_array[i - 1];
 }
 ps->_array[pos] = data;
 ps->_size++;
}

void SeqListErase(PSeq ps, int pos) {    //删除pos位置元素
 assert(ps);
 if (pos<0 || pos>= ps->_size)
  return;
 for (int i = pos+1; i < ps->_size; ++i) {
  ps->_array[i - 1] = ps->_array[i];
 }
 ps->_size--;
}

int SeqListFind(PSeq ps, DataType data) {
 assert(ps);
 for (int i = 0; i < ps->_size; ++i) {
  if (ps->_array[i] == data) {
   return i;
  }
 }
 return -1;
}

int SeqListEmpty(PSeq ps) {
assert(ps);
 if (ps->_size == 0) {
  return -1;
 }
 return 0;
}

int SeqListSize(PSeq ps) {
 assert(ps);
 return ps->_size;
}

int SeqListCapacity(PSeq ps) {
 assert(ps);
 return ps->_capacity;
}

void SeqListClear(PSeq ps) {  //清空顺序表元素,直接将有效元素置零
 assert(ps);
 ps->_size = 0;
}

void SeqListRemove(PSeq ps, DataType data) {  //查找值为data的元素并将它删除
 assert(ps);
 int ret = SeqListFind( ps, data);
 if (ret != -1) {
  SeqListErase(ps, ret);
 }
 else
  printf("没有找到值为data的元素!\n");
}

void SeqListDestory(PSeq ps) {
 if (ps->_array) {
  free(ps->_array);
  ps->_array = NULL;
  ps->_capacity = 0;
  ps->_size = 0;
 }
}

void CheckCapacity(PSeq ps) {
 assert(ps);
 if (ps->_size == ps->_capacity) {
  //printf("空间不足,进行扩容!\n");
  int newCapacity = ps->_capacity * 2;
  int* p = (DataType*)malloc(sizeof(DataType)*ps->_capacity);
  if (p == NULL) {
   assert(0);
   return;
  }
  for (int i = 0; i < ps->_size; ++i) {
   p[i] = ps->_array[i];
  }
  free(ps->_array);
  ps->_array = p;
  ps->_capacity = newCapacity;
 }
 }

void PrintSeqList(PSeq ps) {
 assert(ps);
 for (int i = 0; i < ps->_size; ++i) {
  printf("%d ", ps->_array[i]);
 }
 printf("\n");
}

void main() {
 int capacity = 10;
 SeqList s;
 SeqListInit(&s, 10);
 SeqListPushBack(&s, 1);
 SeqListPushBack(&s, 2);
 SeqListPushBack(&s, 6);
 SeqListPushBack(&s, 7);
 PrintSeqList(&s);
 SeqListInsert(&s, 1, 5);
 PrintSeqList(&s);
 SeqListErase(&s, 2);
 PrintSeqList(&s);
 SeqListRemove(&s, 2);
 PrintSeqList(&s);
 //SeqListDestory(&s);
 system("pause");
 return;
}

最终通过主函数来调用各个模块,从而验证各个模块的正确性。这里只显示一个扩容的结果。
初始capacity的值是10.
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值