数据结构C语言版 线性表的动态分配顺序存储结构表示和实现文库

合集下载

清华严蔚敏《数据结构》的的全部代码实现C语言.doc

清华严蔚敏《数据结构》的的全部代码实现C语言.doc

/* c1.h (程序名 ) */#include <string.h>#include <ctype.h>#include <malloc .h> /* malloc() 等 */#include <limits.h> /* INT _MAX 等 */#include <stdio.h> /* EOF(=^Z 或 F6),NULL */#include <stdlib.h> /* atoi() */#include <io.h> /* eof() */#include <math.h> /* floor(),ceil(),abs() */#include <process.h> /* exit() *//* 函数结果状态代码*/#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1/* #define OVERFLOW -2因为在math.h中已定义OVERFLOW的值为3,故去掉此行*/ typedef int Status; /* Status 是函数的类型 ,其值是函数结果状态代码,如OK 等 */typedef int Boolean ; /* Boolean 是布尔类型 ,其值是 TRUE 或 FALSE *//* algo2-1.c 实现算法 2.1 的程序*/#include"c1.h"typedef int ElemType ;#include"c2-1.h"/*c2-1.h线性表的动态分配顺序存储结构*/#define LIST_INIT_SIZE10 /*线性表存储空间的初始分配量*/#define LISTINCREMENT 2/* 线性表存储空间的分配增量*/typedef struct{ElemType *elem ; /* 存储空间基址*/int length; /*当前长度*/int listsize; /* 当前分配的存储容量(以 sizeof(ElemType )为单位 ) */}SqList;#include "bo2-1.c"/* bo2-1.c顺序表示的线性表(存储结构由c2-1.h 定义 )的基本操作 (12 个) */ Status InitList (SqList *L ) /* 算法 2.3 */{ /* 操作结果:构造一个空的顺序线性表*/(*L ).elem=(ElemType*) malloc ( LIST_INIT_SIZE * sizeof(ElemType));if (!( *L ).elem)exit (OVERFLOW); /* 存储分配失败*/(*L ).length=0; /*空表长度为0 */(*L ).listsize =LIST_INIT_SIZE ; /*初始存储容量*/return OK;}Status DestroyList (SqList *L ){ /* 初始条件:顺序线性表L 已存在。

数据结构(c语言版).

数据结构(c语言版).

严蔚敏 清华大学 谭浩强 清华大学 徐孝凯 电子工业 张基温 电子工业 庞丽萍 华中科技大学
数据库基础与应用 王 利 中央电大
ISBN 7-5084-1648-1 / TP. 706 网页制作实例教程 齐建玲 中国水利水电 …


… 返回
【例1-2】磁盘目录结构和文件管理系统
root bin math ds sw lib user zhao jiang shao li etc
四类数据基本结构的示意图:
(a)集合结构
(b)线性结构
(c)树型结构
(d)图形结构
由以上例子可见,描述这类非数值计算问题的数学模型和
方法不再是数学方程,而是诸如线性表、树和图之类的数据
结构。
数据结构示例 【例1-1】图书目录表
由于表中每条记录(表示每一本书)的登录号各不相同,
所以可用登录号来唯一地标识每条记录(一本图书)。在计
5.什么是存储结构?主要有哪些主要的存储结构?
数据的存储结构:数据的存储方式.反映数据在计算 机内部的存储形式,是逻辑结构在计算机中的实现 方法. 数据既可以顺序存储在内存中如数组存储,也可以 离散存储在内存中(动态内存分配,指针管理). 如线性结构举例. 数据的常用存储结构:顺序存储结构和链式存储结 构. 以及散列、索引结构.
数据结构:非数值计算的程序设计问题中数据元素 以及它们之间的关系和操作的总称. 程序设计中数据是必须的,但是否应用数据结构则 并不是必需的.
4.数据结构的抽象和一般对象的抽象其主要不同 点是什么?
对象的抽象:与需求密切相关. 如:身份证管理侧重于人的籍贯,出生年月和 身份证号和住址. 而学籍管理关心的学生 的学号,姓名和成绩单. 数据结构的抽象:与需求一般是无关的.只是与管 理和访问数据的方式有关.任意类型的数据都可 以采用统一的接口来操作.

《数据结构与算法(C++语言版)》第2章 线性表

《数据结构与算法(C++语言版)》第2章 线性表
• 以下是一个使用类LinearList的C++程序,它假定之前的程 序均存储在LinearList.h之中,且异常类定义位于文件 exception.h之中。该示例完成以下操作:创建一个大小为5 的整数线性表L;输出该表的长度(为0);在第0个元素之 后插入2;在第一个元素之后插入6和8(至此,线性表为2, 6,8);寻找并输出第一个元素(为2);输出当前表的长 度(为3);删除并输出第一个元素。
数据结构与算法 (C++语言版)
第2章 线性表
线性表的类型定义
• 基本概念 • 线性表是由n(n≥0)个类型相同的数据元素组成的有限序 列,通常表示为L=(a1, …, ai–1, ai, ai+1, …, an)。其中,L为线 性表名称,ai为组成该线性表的数据元素,ai–1领先于ai,ai 领先于ai+1,称ai–1是ai的直接前驱元素,ai+1是ai的直接后继 元素。当i=1, 2, …, n–1时,ai有且仅有一个直接后继;当 i=2, 3, …, n时,ai有且仅有一个直接前驱。 • 线性表的长度就是线性表中元素的个数n(n≥0)。当n=0时, 称为空表。在非空表中的每个数据元素都有一个确定的位 置,如a1是第一个数据元素,an是最后一个数据元素,ai是 第i个数据元素。称i为数据元素ai在线性表中的位序。
线性表的类型定义
Prev_Elem(L, cur_e, &pre_e) //返回当前元素的前一个元素值 输入:线性表L。 输出:若cur_e是线性表L的数据元素,且不是第一个,则用 pre_e返回它的直接前驱元 素;否则操作失败,pre_e无定义。 Next_Elem(L, cur_e, &next_e) //返回当前元素的后一个元素值 输入:线性表L。 输出:若cur_e是线性表L的数据元素,且不是最后一个,则用 next_e返回它的直接后继元素;否则操作失败,next_e无定 义。

动态分配的顺序线性表的十五种操作—C语言实现

动态分配的顺序线性表的十五种操作—C语言实现

动态分配的顺序线性表的⼗五种操作—C语⾔实现线性表定义:是最常⽤的,也是最简单的数据结构,是长度为n个数据元素的有序的序列。

含有⼤量记录的线性表叫⽂件记录:稍微复杂的线性表⾥,数据元素为若⼲个数据项组成,这时把⼀个数据元素叫记录结构特点:在⾮空有限的条件下,存在唯⼀的⼀个表头结点,唯⼀的⼀个表尾结点,除去第⼀个元素之外,每个数据元素都只有⼀个前驱,除去最后⼀个元素之外,每⼀个数据元素都只有⼀个后继。

注意:线性表中的数据元素可以是各种各样的,但同⼀线性表中的元素必定具有相同特性(属于同⼀数据对象,类似数组)。

线性表的数据元素间有序偶关系。

线性表的顺序表⽰和实现有⼀组地址连续的内存单元,在这些连续的内存单元⾥,顺次地存储线性表⾥的数据元素特点:逻辑地址和物理地址都是连续的,适合随机存取。

假设&a1为线性表的基址,每个数据元素占据L个存储单位。

那么表⾥第i个元素的存储地址:&a(i) = &a(1) + (i - 1)x L线性表的顺序表⽰结构(顺序映象)也叫顺序表,顺序表中元素的逻辑关系和物理位置⼀致,是⼀种随机存取的存储结构。

(类似⾼级语⾔⾥的数组,通常⽤数组描述数据结构的顺序存储结构)。

如果⽤数组表⽰顺序表,那很简单,也不实⽤,不能改变存储容量,下⾯是动态分配的顺序表的表⽰和操作ADT.h头⽂件1/************************************************************************/2/* 功能:声明常量和函数原型的头⽂件,线性表的动态分配顺序存储结构3/* 作者:dashuai4/************************************************************************/5 #include <stdio.h>6 #include <stdlib.h>7#define LIST_INIT_SIZE 100//线性表初始化存储空间分配8#define LISTINCREMENT 10//线性表存储空间的分配增量910 typedef struct{//此时可以省去结构标记11int *elem;//线性表基址12int length;//当前表长13int listsize;//当前为线性表分配的存储容量14 } SqList;//为结构起的别名SqList1516//线性表常⽤的有13个操作,归为4类1718/************************************************************************/19/*第⼀类:初始化操作,记住各种数据结构开始使⽤都要初始化 */20/************************************************************************/2122//1、线性表的初始化,构造⼀个空的线性表23int InitList(SqList *L);//因为要改变线性表,必须⽤指针做参数2425/************************************************************************/26/*第⼆类:销毁操作,记住各种数据结构使⽤了都要有销毁的步骤 */27/************************************************************************/2829//2、销毁,释放内存操作30void Destory(SqList *L);//直接把内存释放的操作!类似与free()3132/************************************************************************/33/* 第三类:引⽤型操作,操作不改变线性表⾥的数据元素,也不改变他们之间的关系*/34/************************************************************************/3536//3、判空操作,若线性表已经存在,为空⽩则返回true,否则返回false37void ListEmpty(SqList L);3839//4、求长度操作,若线性表已经存在,则返回表L中元素个数40int ListLength(SqList L);4142//5、定位操作:线性表 L 已存在,返回 L 中第 1 个与 e 满⾜相等关系的元素的位序。

C语言数据结构线性表教程示例详解

C语言数据结构线性表教程示例详解

C语⾔数据结构线性表教程⽰例详解⽬录线性表顺序表线性表数据结构⾥我们时常看到什么什么表,线性表是最基本、最简单、也是最常⽤的⼀种数据结构,其他各种表的万恶之源就是这个线性表,他是个啥其实顾名思义:⼀个线性表是n个具有相同特性的数据元素的有限序列。

数据元素之间的关系是⼀对⼀的关系,即除了第⼀个和最后⼀个数据元素之外,其它数据元素都是⾸尾相接的(注意,这句话只适⽤⼤部分线性表,⽽不是全部。

⽐如,循环链表逻辑层次上也是⼀种线性表(存储层次上属于链式存储,但是把最后⼀个数据元素的尾指针指向了⾸位结点)。

说的这么复杂其实就是下⾯这个模型,线性表的逻辑结构简单,便于实现和操作。

因此,线性表这种数据结构在实际应⽤中是⼴泛采⽤的⼀种数据结构。

⽽我们说的线性是指他的连续性,并⾮是内存上连续,⽽是逻辑上连续,什么⼜是逻辑上连续?我们说数据结构有两种结构,⼀是物理结构即在内存中怎么存,⼆是逻辑结构是我们假想的。

物理结构其实⾮数组即链表,基本都逃不开这俩,但数组有个致命的缺陷就是不知道咱要存多少,我开辟10个空间,若想存第11个就是放屁,那直接给他1000个空间呢?那剩下989个空间直接浪费掉,⼀句话就是他不能按需所取。

这时链表就应运⽽⽣,我们有⼏个数据就开辟⼏个空间,众所周知数组我们得到⾸元素地址,直接遍历就能得到全部成员,那它怎么去串联这些独⽴零散的空间来建⽴联系?我们按需所取⾸先就会选择去堆区申请空间,去堆区不是⼀定是最好,因为malloc 函数嘛,满⾜要就拿不要就释放。

我们对数据寻踪觅迹是通过其对应的地址对吧,不难想到应⽤指针吧,这样那我们就可以“有备⽽来”,在开辟数据空间时多开辟4到8个字节来存放指针,最后⼀个数据我们不需要指针了,直接放⼀个空指针就⾏。

顺序表线性表主要由顺序表⽰或链式表⽰。

在实际应⽤中,常以栈、队列、字符串等特殊形式使⽤。

顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指⽤⼀组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采⽤顺序存储结构的线性表通常称为顺序表。

数据结构(C语言版)

数据结构(C语言版)

比较
Prim算法适用于稠密图, Kruskal算法适用于稀疏图;
两者时间复杂度相近,但 Kruskal算法需额外处理并查
集数据结构。
最短路径算法设计思想及实现方法比较
1 2
Dijkstra算法
从源点出发,每次找到距离源点最近的顶点并更 新距离值,直至所有顶点距离确定。适用于不含 负权边的图。
Floyd算法
特殊二叉树
满二叉树、完全二叉树等。
二叉树的遍历与线索化
二叉树的遍历
前序遍历、中序遍历、后序遍历和层 次遍历是二叉树的四种基本遍历方法 。
线索化二叉树
为了方便查找二叉树节点的前驱和后 继,可以对二叉树进行线索化处理, 即在节点的空指针域中存放指向前驱 或后继的指针。
树和森林的遍历与转换
树的遍历
01
串的顺序存储结构
01
02
03
串的顺序存储结构是用 一组地址连续的存储单 元来存储串中的字符序
列的。
按照预定义的大小,为 每个定义的串变量分配 一个固定长度的存储区 ,一般是用定长数组来
定义。
串值的存储:将实际串 长度值保存在数组的0下 标位置,串的字符序列 依次存放在从1开始的数
组元素中。
串的链式存储结构
03
比较
DFS空间复杂度较低,适用于递 归实现;BFS可找到最短路径, 适用于非递归实现。
最小生成树算法设计思想及实现方法比较
Prim算法
从某一顶点开始,每次选择当 前生成树与外界最近的边加入 生成树中,直至所有顶点加入

Kruskal算法
按边权值从小到大排序,依次 选择边加入生成树中,保证不
形成环路。
数据结构(C语言版)

数据结构C语言版 线性表的单链表存储结构表示和实现

数据结构C语言版 线性表的单链表存储结构表示和实现

#include 〈stdio.h>#include <malloc。

h>#include 〈stdlib.h>/*数据结构C语言版线性表的单链表存储结构表示和实现P28—31编译环境:Dev-C++ 4。

9。

9。

2日期:2011年2月10日*/typedef int ElemType;// 线性表的单链表存储结构typedef struct LNode{ElemType data; //数据域struct LNode *next;//指针域}LNode, *LinkList;// typedef struct LNode *LinkList;// 另一种定义LinkList的方法// 构造一个空的线性表Lint InitList(LinkList *L){/*产生头结点L,并使L指向此头结点,头节点的数据域为空,不放数据的。

void *malloc(size_t)这里对返回值进行强制类型转换了,返回值是指向空类型的指针类型.*/(*L)= (LinkList)malloc(sizeof(struct LNode) );if( !(*L))exit(0);// 存储分配失败(*L)-〉next = NULL;// 指针域为空return 1;}// 销毁线性表L,将包括头结点在内的所有元素释放其存储空间。

int DestroyList(LinkList *L){LinkList q;// 由于单链表的每一个元素是单独分配的,所以要一个一个的进行释放while(*L ){q = (*L)—〉next;free(*L );//释放*L = q;}return 1;}/*将L重置为空表,即将链表中除头结点外的所有元素释放其存储空间,但是将头结点指针域置空,这和销毁有区别哦。

不改变L,所以不需要用指针。

*/int ClearList( LinkList L ){LinkList p,q;p = L—〉next;// p指向第一个结点while( p ) // 没到表尾则继续循环{q = p—>next;free( p );//释放空间p = q;}L—>next = NULL; // 头结点指针域为空,链表成了一个空表return 1;}// 若L为空表(根据头结点L—〉next来判断,为空则是空表),则返回1,// 否则返回0.int ListEmpty(LinkList L){if(L—>next ) // 非空return 0;elsereturn 1;}// 返回L中数据元素个数。

C语言实现顺序表的基本操作(从键盘输入生成线性表,读txt文件生成线性表和数组生成线性表-。。。

C语言实现顺序表的基本操作(从键盘输入生成线性表,读txt文件生成线性表和数组生成线性表-。。。

C语⾔实现顺序表的基本操作(从键盘输⼊⽣成线性表,读txt⽂件⽣成线性表和数组⽣成线性表-。

经过三天的时间终于把顺序表的操作实现搞定了。

(主要是在测试部分停留了太长时间)1. 线性表顺序存储的概念:指的是在内存中⽤⼀段地址连续的存储单元依次存储线性表中的元素。

2. 采⽤的实现⽅式:⼀段地址连续的存储单元可以⽤固定数组或者动态存储结构来实现,这⾥采⽤动态分配存储结构。

3. 顺序表结构体⽰意图三种写法完整代码:第⼀种写法. 从键盘输⼊⽣成线性表--完整代码如下,取值操作实际上就是删除操作的部分实现,这⾥就不写了#include<stdio.h>#include<stdlib.h>#include<malloc.h>#define LIST_INIT_SIZE 100#define LISTINCREMENT 10#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2#define TRUE 1#define FALSE 0typedef int Status;typedef int ElemType;typedef struct SqList{ElemType *elem;int length;int listsize;}SqList;Status InitList(SqList &L){L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));if (!L.elem){printf("ERROR\n");return ERROR;}L.length = 0;L.listsize = LIST_INIT_SIZE;return OK;}Status ListEmpty(SqList L) //判空{if (L.length = 0) return TRUE;else return FALSE;}Status ListInsert(SqList &L, int i, ElemType e) //插⼊{ElemType *p, *q;ElemType *newbase;int j;if (i < 1 || i > L.length + 1) return ERROR;if (L.length >= L.listsize){newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));if (newbase == NULL){printf("realloc failed!\n");return ERROR;//exit(-1);}L.elem = newbase;L.listsize += LISTINCREMENT;}p = L.elem+i-1;for( q = L.elem + L.length - 1; q>= p; --q ){*(q+1) = *q;}*p = e;++L.length;return OK;}Status CrtList(SqList &L) // 从键盘输⼊数据⽣成线性表{printf("输⼊整数,以0结束:\n");ElemType e;int i = 1;scanf("%d", &e);while (e != 0){if (!ListInsert(L, i, e)) return ERROR;i++;scanf("%d", &e);}return OK;}Status CrtList2(SqList &L, ElemType d[], int n) // 从数组⽣成线性表{int i;for (i = 0; i < n; ++i){if (!ListInsert(L, i + 1, d[i])) return ERROR;}return OK;}Status ListDelet(SqList &L, int i, ElemType &e) //删除{if ((i<1) || (i>L.length)) return ERROR;ElemType *p, *q;p = &(L.elem[i - 1]);e = *p;q = L.elem + L.length - 1;for (++p; p <= q; ++p) *(p - 1) = *(p);--L.length;return OK;}Status GetElem(SqList &L, int i, ElemType &e) //取值{if ((i <= 0) || (i>L.length)) return ERROR;else{e = L.elem[i - 1];return OK;}}Status compare(ElemType a, ElemType b) //⽐较{if (a == b) return TRUE;else return FALSE;}int LocateElem(SqList L, ElemType e) //定位{Status compare(ElemType a, ElemType b);int i;for (i = 0; i<L.length; i++){if (compare(L.elem[i], e))return ++i;}if (i == L.length) return0;}Status PriorElem(SqList L, ElemType cur_e, ElemType &pre_e) //求直接前驱{int LocateElem(SqList L, ElemType e);int i = LocateElem(L, cur_e);if ((i == 0) || (i == 1)) return ERROR;pre_e = L.elem[i - 2];return OK;}int ListLength(SqList L) //求长度{int length = L.length;return length;}void MergeList(SqList La, SqList Lb, SqList &Lc) //归并{Lc.length = La.length + Lb.length;Lc.listsize = Lc.length;Lc.elem = (ElemType*)malloc(Lc.length*sizeof(ElemType));if (Lc.elem == NULL) exit(OVERFLOW);int i, j, k;for (i = 0, j = 0, k = 0; (i<La.length) && (j<Lb.length); k++){if (La.elem[i]<Lb.elem[j]){Lc.elem[k] = La.elem[i];i++;}else{Lc.elem[k] = La.elem[j];j++;}}while (i<La.length){Lc.elem[k] = La.elem[i];i++;k++;}while (j<Lb.length){Lc.elem[k] = Lb.elem[j];j++;k++;}}void vist(ElemType e){printf("%d ", e);}Status ListTraverse(SqList L) //遍历{int i;if (L.length == 0) printf("⽆元素");for (i = 0; i<L.length; i++){vist(L.elem[i]);}if (i == L.length){printf("\n");return OK;}else return ERROR;}Status ListClear(SqList L) //清空{if (L.elem == NULL) return ERROR;int i;for (i = 0; i<L.length; i++) L.elem[i] = 0;L.length = 0;return OK;}Status DestroyList(SqList &L) //销毁{if (L.elem == NULL) return ERROR;free(L.elem);L.length = 0;L.listsize = 0;return OK;}void PrnList(SqList L) //打印{int i;for (i = 0; i < L.length; ++i){printf("%5d", L.elem[i]);}printf("\n");}int main(){int j, l;ElemType e, e1;SqList La;if (InitList(La)) printf("OK\n");else exit(INFEASIBLE);CrtList(La);PrnList(La);int k;printf("1:判空\n2:插⼊\n3:删除\n4:定位\n5:求长度\n6:直接前驱\n");printf("7:归并\n8:遍历\n9:清空\n10:销毁\n\n0:退出\n");scanf("%d", &k);while (k != 0){switch (k){case1:if (ListEmpty(La)) printf("empty\n");else printf("non-empty\n");break;case2:printf("在第⼏个位置插⼊何数:");scanf("%d%d", &j, &e);if (ListInsert(La, j, e)) printf("OK\n");else printf("ERROR\n");break;case3:printf("删除第⼏个数:");scanf("%d", &j);if (ListDelet(La, j, e))PrnList(La);printf("删除数为:%d\n", e);break;case4:printf("定位数字:");scanf("%d", &e);if (LocateElem(La, e) != 0) printf("OK,位序为:%d\n", LocateElem(La, e));else printf("ERROR\n");break;case5:l = ListLength(La);printf("ListLength=%d\n", l);break;case6:printf("寻找何数直接前驱:");scanf("%d", &e);if (PriorElem(La, e, e1)) printf("前驱为:%d\n", e1);else printf("ERROR\n");break;case7:SqList Lb, Lc;if (InitList(Lb)) printf("OK\n");else printf("ERROR\n");CrtList(Lb);MergeList(La, Lb, Lc);printf("有序归并后:\n");PrnList(Lc);break;case8:if (ListTraverse(La)) printf("遍历成功\n");else printf("遍历失败\n");break;case9:if (ListClear(La)) printf("清空成功\n");else printf("清空失败\n");break;case10:if (DestroyList(La)) printf("销毁完成\n");else printf("销毁失败\n");return0;default:printf("ERROR\n");}scanf("%d", &k);}return0;}View Code第⼆种写法. 从txt⽂件读⼊⽣成线性表--完整代码如下:#include<stdio.h>#include<stdlib.h>#define OK 1#define ERROR 0#define OVERFLOW -1#define TRUE 1#define FALSE 0#define INIT_LIST_SIZE 100#define LISTINCREMENT 10typedef int Status;typedef int ElemType;typedef struct{ElemType *elem;int length;int listsize;}SqList;Status InitList(SqList *L){L->elem = (ElemType*)malloc(INIT_LIST_SIZE*sizeof(ElemType));if (!L->elem) exit(OVERFLOW);L->length = 0;L->listsize = INIT_LIST_SIZE;return OK;}Status ListEmpty(SqList L) //判空{if (L.length = 0) return TRUE;else return FALSE;}Status ListInsert(SqList *L, int i, ElemType e) //插⼊{ElemType *newbase, *q, *p;if (i<1 || i>L->length + 1) return ERROR;if (L->length>L->listsize){newbase = (ElemType*)realloc(L->elem, (L->listsize + LISTINCREMENT)*sizeof(ElemType));if (!newbase) exit(OVERFLOW);L->elem = newbase;L->listsize += LISTINCREMENT;}q = L->elem + i - 1; //q为插⼊位置for (p = L->elem + L->length - 1; p >= q; p--){*(p + 1) = *p;}*q = e;++L->length;return OK;}Status ListDelete(SqList *L, int i, ElemType * e) //删除{ElemType * p, *q;if (i<1 || i>L->length) return ERROR;p = L->elem + i - 1; //p为被删除元素位置*e = *p; //被删除元素的值赋值给eq = L->elem + L->length - 1; //表尾元素位置for (++p; p <= q; ++p){*(p - 1) = *p;}L->length--;return OK;}Status GetElem(SqList *L, int i, ElemType * e) //取值{if (i<1 || i>L->length) return ERROR;*e = *(L->elem + i - 1); //获取第i个元素的地址return OK;}int LocateElem(SqList L, ElemType e) //定位{int i;for (i = 0; i<L.length; i++){if (L.elem[i]==e)return ++i;}if (i == L.length) return0;}Status PriorElem(SqList L, ElemType e, ElemType &pre_e) //求直接前驱{int LocateElem(SqList L, ElemType e);int i = LocateElem(L, e);if ((i == 0) || (i == 1)) return ERROR;pre_e = L.elem[i - 2];return OK;}Status GetLength(SqList *L) //求长度{return L->length;}void PrnList(SqList *L) //遍历{int i;for (i = 0; i<(*L).length; i++){if (i == 0)printf("(");printf(" %d ", L->elem[i]);if (i == (*L).length - 1)printf(")\n");}}Status ClearList(SqList *L) //清空{L->length = 0;return OK;}Status Destroy(SqList *L) //销毁{free(L->elem);L->elem = NULL;L->length = 0;L->listsize = 0;return OK;}int main(){int n = 0, rc;int a, i;int e, e1;SqList L;if (InitList(&L)) printf("OK\n");FILE *fp = fopen("D:/1.txt", "r");if (fp == NULL){printf("打开⽂件失败");}printf("从1.txt⽂件读⼊⼏个数:");scanf("%d", &n);for (i = 0; i< n; i++){fscanf(fp, "%d", &a);ListInsert(&L, i+1, a);}fclose(fp);PrnList(&L);char k;printf("\n1.插⼊\n2.删除\n3.取值\n4.定位\n5.直接前驱\n6.求长度\n7.遍历\n8.清空\n9.销毁\n"); while (1){k = getchar();switch (k){case'1':printf("在第⼏个位置插⼊何数:");scanf("%d%d", &i, &e);if (ListInsert(&L, i, e))printf("i=%d,e=%d 已经插⼊\n", i, e);else printf("插⼊失败\n");break;case'2':printf("删除第⼏个数:\n");scanf("%d", &i);if (ListDelete(&L, i, &e))printf("i=%d,e=%d 已经删除\n", i, e);else printf("删除失败\n");break;case'3':printf("取第⼏个数:\n");scanf("%d", &i);if (GetElem(&L, i, &e))printf("第i=%d号,e=%d 被取出!\n", i, e);else printf("取值失败\n");break;case'4':printf("定位数字:");scanf("%d", &e);if (LocateElem(L, e) != 0) printf("OK,位序为:%d\n", LocateElem(L, e));else printf("ERROR\n");break;case'5':printf("寻找何数直接前驱:");scanf("%d", &e);if (PriorElem(L, e, e1)) printf("前驱为:%d\n", e1);else printf("ERROR\n");break;case'6':printf("表长为%d\n", GetLength(&L));break;case'7':printf("遍历:\n");PrnList(&L);break;case'8':if (ClearList(&L)) printf("清空成功\n");else printf("清空失败\n");break;case'9':printf("销毁\n");Destroy(&L);printf("销毁成功\n");exit(0);return0;}}return0;}View Code第三种写法:读数组⽣成线性表--完整代码如下:#include<stdlib.h>#define OK 1#define ERROR 0#define OVERFLOW -1#define TRUE 1#define FALSE 0#define INIT_LIST_SIZE 100#define LISTINCREMENT 10typedef int Status;typedef int ElemType;typedef struct{ElemType *elem;int length;int listsize;}Sqlist;Status InitList(Sqlist *L){L->elem = (ElemType *)malloc(INIT_LIST_SIZE *sizeof(ElemType));if (!L->elem)exit(OVERFLOW);L->length = 0;L->listsize = INIT_LIST_SIZE;return OK;}Status ListEmpty(Sqlist L){if (L.length = 0)return ERROR;else return FALSE;}Status ListInsert(Sqlist *L, int i, ElemType e){ElemType *newbase, *p, *q;if (i<1 || i>L->length + 1)return ERROR;if (L->length > L->listsize){newbase = (ElemType *)realloc(L, (L->listsize + LISTINCREMENT)*sizeof(ElemType));if (!newbase)exit(OVERFLOW);L->elem = newbase;L->listsize += LISTINCREMENT;}p = L->elem + i - 1;for (q = L->elem + L->length - 1; q >= p; q--){*(q + 1) = *q;}*p = e;L->length++;return OK;}Status CreateList(Sqlist *L, ElemType element[], int n) // 从数组⽣成线性表{int i;for (i = 0; i < n; ++i){if (!ListInsert(L, i + 1, element[i])) return ERROR;}return OK;}Status ListDelete(Sqlist *L, int i, ElemType *e){ElemType *p, *q;if (i<1 || i>L->length)return ERROR;p = L->elem + i - 1;q = L->elem + L->length - 1;*e = *p;for (p++; q >= p; p++){*(p - 1) = *p;}L->length--;return OK;}Status GetElem(Sqlist *L, int i, ElemType *e){if (i<1 || i>L->length)return ERROR;return OK;}int LocateElem(Sqlist L, ElemType e){int i;for (i = 0; i < L.length; i++)if (L.elem[i] == e)return i + 1;}Status PriorElem(Sqlist L, ElemType e, ElemType &pr_e){int LocateElem(Sqlist L, ElemType e);int i = LocateElem(L, e);if (i<1 || i>L.length)return ERROR;pr_e = L.elem[i - 2];return OK;}Status GetLength(Sqlist *L){return L->length;}void PrnList(Sqlist *L){int i;for (i = 0; i < L->length; i++)printf("%d ", L->elem[i]);printf("\n");}Status ClearList(Sqlist *L){L->length = 0;return OK;}Status Destroy(Sqlist *L){free(L->elem);L->elem = NULL;L->length = 0;L->listsize = 0;return OK;}int main(){int i;int a, n = 0;int e, e1;Sqlist L;ElemType element[] = { 15, 3, 59, 27, 8, 11, 32 };if (InitList(&L))printf("OK\n");CreateList(&L, element, 7);PrnList(&L);char k;printf("\n1.插⼊\n2.删除\n3.取值\n4.定位\n5.直接前驱\n6.求长度\n7.遍历\n8.清空\n9.销毁\n"); while (1){k = getchar();switch (k){case'1':printf("在第⼏个位置插⼊何数:");scanf("%d%d", &i, &e);if (ListInsert(&L, i, e))printf("i=%d e=%d已经插⼊\n", i, e);break;case'2':printf("删除第⼏个数:");scanf("%d", &i);if (ListDelete(&L, i, &e))printf("i=%d e=%d已经删除\n", i, e);break;case'3':printf("取第⼏个数:");scanf("%d", &i);if (GetElem(&L, i, &e))printf("第i=%d e=%d已经取出\n", i, e);break;case'4':printf("定位何数:");scanf("%d", &e);if (LocateElem(L, e))printf("位序为:%d\n", LocateElem(L, e));break;case'5':printf("寻找何数的直接前驱:");scanf("%d", &e);if (PriorElem(L, e, e1))printf("前驱为:%d\n", e1);break;case'6':printf("表长为:%d\n", GetLength(&L));break;case'7':printf("遍历:\n");PrnList(&L);break;case'8':if (ClearList(&L))printf("清空成功!\n");break;case'9':if (Destroy(&L))printf("销毁成功!\n");exit(0);return0;}}return0;}View Code看懂了左⼿给你个栗⼦,给我关注点赞;看不懂右⼿给你个锤⼦,砸开脑壳看看有没有带脑⼦。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构C语言版线性表的动态分配顺序存储结构表示和实现文库.txt爱空空情空空,自己流浪在街中;人空空钱空空,单身苦命在打工;事空空业空空,想来想去就发疯;碗空空盆空空,生活所迫不轻松。

总之,四大皆空!/*数据结构C语言版线性表的动态分配顺序存储结构表示和实现P22-26编译环境:Dev-C++ 4.9.9.2日期:2011年2月9日*/#include <stdio.h>#include <malloc.h>#include <stdlib.h>typedef int ElemType; // 定义数据结构元素的数据类型#define LIST_INIT_SIZE 10 // 线性表存储空间的初始分配量#define LISTINCREMENT 5 // 线性表存储空间的分配增量// 线性表的动态分配顺序存储结构typedef struct{ElemType *elem; // 存储空间基址int length; // 当前长度int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位)}SqList;// 算法2.3,P23// 构造一个空的顺序线性表即对顺序表结构体中的所有元素// 进行初始化。

int InitList(SqList *L){// 分配指定大小的存储空间给顺序表(*L).elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));if( !(*L).elem ) // 存储分配失败exit(0);(*L).length = 0; // 当前长度初始化为0// 指定分配的存储容量(*L).listsize = LIST_INIT_SIZE;return 1;}// 销毁顺序线性表L即将顺序表结构体中的所有成员销毁(空间释放,// 数值置0)。

int DestroyList(SqList *L){// 先释放空间,然后置空free( (*L).elem );(*L).elem = NULL;(*L).length = 0;(*L).listsize = 0;return 1;}// 将L重置为空表(当前长度为0即是空表)。

int ClearList(SqList *L){(*L).length = 0;return 1;}/*若L为空表,则返回1,否则返回0。

如何判断是否为空表呢?结构体中已经包含一个可以说明的元素,那就是length,表示当前顺序表的长度,根据当前的长度就可以判断了,为0就是空表,不为0就不是空表了。

*/int ListEmpty(SqList L){if(0 == L.length)return 1;elsereturn 0;}// 返回L中数据元素个数。

int ListLength(SqList L){// L.length刚好记录了当前顺序表的长度,直接返回return L.length;}// 用e返回L中第i个数据元素的值,第i个数据元素就是L.elem[i-1]。

int GetElem(SqList L,int i,ElemType *e){// 首先进行异常处理if(i < 1 || i > L.length)exit(0);/*注意顺序表基址L.elem[0] 表示第一个数,而第i个数则是用基址L.elem + i - 1来表示,也可以用L.elem[i-1]表示。

为什么可以那样表示呢?因为l.elem是基地址,相当于数组头一样,指示了一个首地址,然后对地址进行加减,形成不同元素的地址。

*是取地址所指的内容,所以*(L.elem+i-1)就是第i个数据的值了。

*/*e = *(L.elem + i - 1);// *e = L.elem[i-1];return 1;}/* 算法2.6,P26返回L中第1个与e满足关系compare()的数据元素的位序。

若这样的数据元素不存在,则返回值为0。

*/int LocateElem(SqList L,ElemType e,int(* compare)( ElemType, ElemType)){ElemType *p;int i = 1; // i的初值为第1个元素的位序p = L.elem; // p的初值为第1个元素的存储位置即地址// 循环比较,直到找到符合关系的元素while(i <= L.length && !compare(*p++, e) )++i;if(i <= L.length)return i;elsereturn 0;}#if 0/* 算法2.7 与算法2.2区别已知顺序线性表La和Lb的元素按值非递减排列。

归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列。

算法的时间复杂度为O(La.length + Lb.length).*/void MergeList(SqList La, SqList Lb, SqList *Lc){ElemType *pa, *pa_last, *pb, *pb_last, *pc;pa = La.elem; //pa指向线性表La的头结点pb = Lb.elem; //pb指向线性表Lb的头结点/* 不用InitList()创建空表Lc */(*Lc).listsize = (*Lc).length = La.length + Lb.length;// pc指向线性表Lc的头结点pc = (*Lc).elem =(ElemType *)malloc((*Lc).listsize*sizeof(ElemType));if( !(*Lc).elem ) /* 存储分配失败 */exit(0);pa_last = La.elem + La.length - 1; //pa_last指向线性表La的尾结点pb_last = Lb.elem + Lb.length - 1; //pb_last指向线性表Lb的尾结点while(pa <= pa_last && pb <= pb_last) /* 表La和表Lb均非空 */{ /* 归并 */if(*pa <= *pb) //*pa更小接到pc后*pc++ = *pa++;else //*pb更小接到pc后*pc++ = *pb++;}while(pa <= pa_last) /* 表La非空且表Lb空 */*pc++ = *pa++; /* 插入La的剩余元素 */while(pb <= pb_last) /* 表Lb非空且表La空 */*pc++ = *pb++; /* 插入Lb的剩余元素 */}#endif// 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否// 则返回0。

int PriorElem(SqList L, ElemType cur_e, ElemType *pre_e){int i = 2;// 因为第一个数据元素无前继,从第二个数据元素开始ElemType *p = L.elem + 1;// 找到该cur_e对应的元素并赋给pwhile(i <= L.length && *p != cur_e){p++;i++;}if(i > L.length)return 0;else{/*将该cur_e的前驱赋给*pre_e.对等式说明下:* 和 --是同优先级的,且它们的结合性是自右向左的,所以先p自减1,p指向其前驱,然后将p所指向的地址的内容赋给*pre_e。

从这里要明白为什么用指针进行传值,我给你一个地址,你把内容放进去,然后我就知道其中的值了。

这就是使用指针的用处。

*/*pre_e = *--p;return 1;}}/*若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则返回0*/int NextElem(SqList L,ElemType cur_e,ElemType *next_e){int i = 1;ElemType *p = L.elem;while(i < L.length && *p != cur_e){i++;p++;}if(i == L.length)return 0;else{/*对这个等式说明下:* 和 --是同优先级的,且它们的结合性是自右向左的,所以先p自加1,然后将p所指向的地址的内容赋给*next_e*/*next_e = *++p;return 1;}}// 算法2.4 P24// 在L中第i个位置之前插入新的数据元素e,L的长度加1.int ListInsert(SqList *L,int i,ElemType e){ElemType *newbase, *q, *p;// 输入的i不合法if(i < 1 || i > (*L).length + 1)return 0;// 当前存储空间已满,增加分配if( (*L).length >= (*L).listsize){// realloc改变(*L).elem所指内存的大小,原始所指内存中的// 数据不变。

newbase = (ElemType *)realloc((*L).elem,((*L).listsize + LISTINCREMENT) * sizeof(ElemType));if( !newbase )exit(0);(*L).elem = newbase; // 新基址(*L).listsize += LISTINCREMENT; // 增加存储容量}// 指定插入的位置q = (*L).elem + i - 1;// q之后的元素右移一步,以腾出位置for(p = (*L).elem + (*L).length - 1; p >= q; --p)*(p+1) = *p;*q = e; // 插入e++(*L).length; // 表长增1return 1;}/* 算法2.5 P25删除L的第i个数据元素,并用e返回其值,L的长度减1.*/int ListDelete(SqList *L,int i,ElemType *e){ElemType *p,*q;// i值不合法if( i < 1 || i > (*L).length)return 0;p = (*L).elem + i - 1; // p为被删除元素的位置*e = *p; // 被删除元素的值赋给eq = (*L).elem + (*L).length-1; // 表尾元素的位置for(++p; p <= q; ++p) // 被删除元素之后的元素左移*(p-1) = *p;(*L).length--; // 表长减1return 1;}// 依次对L的每个数据元素调用函数vi()。

相关文档
最新文档