C语言数据结构--线性表

严蔚敏老师的C语言数据结构一书中,使用的都是伪代码,实际运行总是会出现问题,这里将线性表的伪代码补全,还有完整的程序代码
摘要由CSDN通过智能技术生成

基本概念

线性表,即线性存储结构

由0个或多个数据元素组成的有限序列。

几个关键点:

  • 线性表是一个序列,元素间有顺序
  • 若元素存在多个,则第一个元素无前驱,最后一个元素无后继,其他元素都有且仅有一个前驱和后继
  • 线性表强调是有限的,事实上无论计算机发展到多强大,它所处理的元素都是有限的。

使用线性表存储的数据,如同向数组中存储数据那样,要求数据类型必须一致
线性表可分为

  • 顺序存储结构,简称顺序表
  • 链式存储结构,简称链表

线性表的抽象数据类型

这里的抽象数据结构就类似于Java中的接口,并不能直接使用其中的方法,只是给你提供了方法的规范,使用这些方法需要我们自己为方法添加逻辑

结构初始化操作

  • InitList(&L)

    操作结果:构造一个空的线性表L。

结构销毁操作

  • DestroyList(&L)

    初始条件:线性表 L 已存在。 操作结果:销毁线性表 L。
    8

引用型操作

  • ListEmpty(L) (线性表判空) 初始条件:线性表L已存在。 操作结果:若L为空表,则返回TRUE,否则 FALSE。

  • ListLength(L) (求线性表的长度) 初始条件:线性表L已存在。 操作结果:返回L中元素个数。

  • PriorElem(L, cur_e, &pre_e) (求数据元素的 前驱) 初始条件:线性表L已存在。 操作结果:若cur_e是L的元素,但不是第一个 ,则用pre_e 返回它的前驱,否则操作失败, pre_e无定义。

  • NextElem(L, cur_e, &next_e) (求数据元素的 后继) 初始条件:线性表L已存在。 操作结果:若cur_e是L的元素,但不是最后一 个,则用next_e返回它的后继,否则操作失败 ,next_e无定义。

  • GetElem(L, i, &e) (求线性表中某个数据元素) 初始条件:线性表L已存在,且1≤i≤ListLength (L)。 操作结果:用e返回L中第 i 个元素的值。

  • LocateElem(L, e, compare( )) (定位函数) 初始条件:线性表L已存在,e为给定值, compare( )是元素判定函数。 操 作 结 果 :返回L中第1个与e满 足 关 系 compare( )的元素的位序。若这样的元素不存 在,则返回值为0。

  • ListTraverse(L, visit( )) (遍历线性表) 初始条件:线性表L已存在,visit() 为某个访 问函数。 操作结果:依次对L的每个元素调用函数visit( )。一旦visit( )失败,则操作失败。

加工型操作

  • ClearList(&L) (线性表置空)

    初始条件:线性表L已存在。 操作结果:将L重置为空表。

  • PutElem(&L, i, &e ) (改变数据元素的值)

    初始条件:线性表L已存在,且1≤i≤ListLength (L) 。 操作结果:L中第i个元素赋值同e的值。

  • ListInsert(&L, i, e ) (插入数据元素)

    初始条件:线性表L已存在,且1≤i≤ListLength (L)+1 。 操作结果:在L的第i个元素之前插入新的元素 e,L的长度增1。

  • ListDelete(&L, i, &e) (删除数据元素)

    初始条件 : 线 性 表 L 已 存 在 且 非 空 , 1≤i≤ListLength (L)。 操作结果:删除L的第i个元素,并用e返回其 值,L的长度减1。

合并操作的伪代码:

void unionL(){
   

	int List1_length, List2_length, i;
	List1_length = ListLength(*List1);//List1的长度
	List2_length = ListLength(*List2);//List2的长度
	
	//将List2中的数据插入到List1中
	for (i = 1; i<= List2_length; i++) {
   

		//先遍历List2中的数据元素

		GetElem(List, i, &e);

		//判断List1中有无该元素,如无,插入
		if ( !LocateElem(*List1, e ) ) {
   
			ListInsert(*List1, ++List1_length, e);
		}
	}	
}

顺序表

存储结构

顺序表存储数据时,会提前申请一整块足够大小的物理空间,然后将数据依次存储起来,存储时做到数据元素之间不留一丝缝隙。

在这里插入图片描述

注意,线性表的第一个位置是从1开始的

动态分配顺序存储结构

#define LIST_INIT_SIZE 100    //线性表存储空间的初始分配量
#define LISTINCREMENT 10   //线性表存储空间的分配增量

typedef int Status;
typedef char ElemType;

typedef struct{
   
	ElemType *elem;  //存储空间基址
	int length;             //当前长度
	int listsize;            //当前分配的存储容量
}SqList;

优点

  • 无须为表示表中元素之家男的逻辑关系而增加额外的存储空间
  • 可以快速的存取表中任意位置的元素

缺点

  • 插入和删除操作需要移动大量元素
  • 当线性表长度变化较大时,难以确定存储空间的容量
  • 容易造成存储空间的“碎片”
#include <stdio.h>
#include <stdlib.h>

#define InitSize 5
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status;
typedef int ElemType;
typedef struct{
   
	ElemType *data;		//存储空间基址,即动态分配数组的指针
	int MaxSize;		//顺序表的最大容量
	int length;			//顺序表的当前长度
}SeqList;				//顺序表的类型定义

/*初始化顺序表*/
Status InitList(SeqList &L){
   
	L.data=(int *)malloc(InitSize*sizeof(int));		//使用malloc函数申请一片连续的空间
	if(!L.data){
   
		printf("初始化失败!!!");
		exit(OVERFLOW);
	}
	L.length = 0;
	L.MaxSize = InitSize;
	return OK;
}

/*增加动态数组的长度*/
void IncreaseSize(SeqList &L, int len){
   
	int *p = L.data;
	L.data = (int *)malloc((L.MaxSize+len)*sizeof(int));
	for(int i=0; i<L.length; i++){
   
		L.data[i] = p[i];
	}
	L.MaxSize = L.MaxSize+len;
	free(p);
}

/*插入操作,在表L中的第i个位置上插入指定元素e*/
Status ListInsert(SeqList &L, int i, int e){
   
	if(i<1 || i>L.length+1){
   
		return ERROR;
	}
	if(L.length >= L.MaxSize){
   
		printf("当前空间不足,正在为其分配空间,请稍后。。。。");
		IncreaseSize(L,5);
		printf("分配成功!!!\n");
	}
	for(int j=L.length; j>=i; j--){
   
		L.data[j
  • 9
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值