数据结构之顺序表

顺序表

说起数据结构(清华大学出版社)这本书,学到的第一个数据结构就是顺序表,顾名思义顺序表啥意思呢,就是字面意思。指用一组地址连续的存储单元依次存储线性表中的各个元素,使得线性表在逻辑结构上相邻的元素存储在连续的物理存储单元中,即:通过数据元素物理存储的连续性来反应元素之间逻辑上的相邻关系。采用顺序存储结构存储的线性表通常简称为顺序表。 我们最常用的数组,其实就是一种顺序表中的典型。

  • 顺序表存储示意

    在这里插入图片描述
  • c语言定义顺序表储存结构

    typedef struct SeqList
    {
    	DataType array[MAX_SIZE];
    	int size; //1.保存顺序表里已经存了的数据个数;
    			  //2.当前用下标。
    } SeqList;
    
    1. DataType 的作用,我们知道在实际使用数据结构时,我们不免需要用到各种类型的数据,那么DataType的作用,就是预先不给定具体类型,由使用者决定是什么类型,这种思想叫做泛型编程。
    2. MAX_SIZE的作用,不给定具体数字大小,而使用常量,为了代码的灵活,如果多次需要这个量,那么我们设置其为常量不是更好吗?
  • 预定义

    // 抽象类型 数据本身不仅仅是数组,更以各种形式所表现。
    typedef int DataType;
    #define MAX_SIZE 100
    
  • 顺序表需要设置那些接口?

    用户基本业务需求就是CRUD(增删改查),那么顺序表自身呢,就需要初始化和销毁的完整生命周期。
    • 初始化和销毁
      • 初始化
        void SeqListInit(SeqList* pSeq) {
        // 1.初始化size
        // 2.可能需要把容器清空
        // 1. assert(pSeq != NULL)
        // 2.if(pSeq != NULL)
        	assert(pSeq != NULL);
        	pSeq->size = 0;
        // memset(pSeq->array, 0, MAX_SIZE)
        }
        
        assert的作用是先计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。
      • 销毁
        // 销毁
        void SeqListDestroy(SeqList* pSeq) {
        	assert(pSeq);
        	pSeq->size = 0;
        }
        
    • 增加数据
      分为三种情况
      1. 加在头
      2. 加在尾
      3. 加在中间
        注意:前提条件是顺序表不能满
      • 头插
        void SeqListPushFront(SeqList* pSeq, DataType data) {
        	assert(pSeq);
        	if (pSeq->size == MAX_SIZE)
        	{
        		return;
        	}
        	//从最后元素,向更后搬运
        	// i代表位置
        	for (int i = pSeq->size; i > 0; i--)
        	{
        		pSeq->array[i] = pSeq->array[i - 1];
        	}
        	// i代表数据
        	/*for (int i = pSeq->size - 1; i >= 0; i--)
        	{
        		pSeq->array[i + 1] = pSeq->array[i];
        	}*/
        	pSeq->array[0] = data;
        	pSeq->size++;
        }
        
      • 尾插
        void SeqListPushBack(SeqList* pSeq, DataType data) {
        	assert(pSeq);
        	//特殊情况 1. 满了
        	if (pSeq->size == MAX_SIZE)
        	{
        		assert(0);
        		return;
        	}
        	//通常情况
        	pSeq->array[pSeq->size] = data;
        	pSeq->size++;
        }
        
      • 选择插入(中间插)
        void SeqListPushIndex(SeqList* pSeq,int index, DataType data) {
        	assert(pSeq);
        	assert(index >= 0 && index <= pSeq->size);
        	if (pSeq->size == MAX_SIZE)
        	{
        		return;
        	}
        	for (int i = pSeq->size; i > index; i--)
        	{
        		pSeq->array[i] = pSeq->array[i - 1];
        	}
        	pSeq->array[index] = data;
        	pSeq->size++;
        }
        
    • 删除数据

      与插入一样分为三种情况
      • 尾删

        void SeqListPop(SeqList* pSeq) {
        	assert(pSeq);
        	// 特殊情况 空了
        	if (pSeq->size == 0)
        	{
        		return;
        	}
        	// 通常情况
        	pSeq->size--;
        }
        
      • 头删

        void SeqListPopFront(SeqList* pSeq) {
        	assert(pSeq);
        
        	if (pSeq->size == 0)
        	{
        		printf("空的\n");
        		return;
        	}
        
        	for (int i = 0; i < pSeq->size-1; i++)
        	{
        		pSeq->array[i] = pSeq->array[i + 1];
        	}
        	pSeq->size--;
        }
        
      • 选择删除

        void SeqListErase(SeqList* pSeq, int index) {
        	assert(pSeq);
        	assert(index >= 0 && index <= pSeq->size - 1);
        	if (pSeq->size == 0)
        	{
        		printf("空的");
        		return;
        	}
        	for (int i = index; i < pSeq->size-1; i++)
        	{
        		pSeq->array[i] = pSeq->array[i + 1];
        	}
        	pSeq->size--;
        }
        
    • 查找数据
      //找到第一个遇到的数的下标, 没找到返回 -1
      int SeqListFind(SeqList* pSeq, DataType data) {
      	//二分查找 有序
      	for (int i = 0; i < pSeq->size; i++)
      	{
      		if (data == pSeq->array[i])
      		{
      			return i;
      		}
      	}
      	return -1;
      }
      		//根据输入的元素,删除遇到的第一个数据.
      void SeqListRemove(SeqList* pSeq, DataType data) {
      	int index = SeqListFind(pSeq, data);
      	if (index == -1)
      	{
      		return;
      	}
      	SeqListErase(pSeq, index);
      }
      //删除遇到的所有数据
      void SeqListRemoveAll(SeqList* pSeq, DataType data) {
      	DataType* extra = (DataType*)malloc(sizeof(DataType) * pSeq->size);
      	int i = 0, j = 0;
      	for (; i < pSeq->size; i++)
      	{
      		if (pSeq->array[i] != data)
      		{
      			extra[j++] = pSeq->array[i];
      		}
      	}
      	for (int k = 0; k < j; k++)
      	{
      		pSeq->array[k] = extra[k];
      	}
      	pSeq->size = j;
      	free(extra);
      }
      

写在最后

最近推出了公众号 coding趣谈,一位在读学生的技术提升之路,为您提供一系列我在学习路上的笔记,经验,以及感悟。往与君共勉,共同进步! 欢迎大家来关注哦!
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值