严蔚敏数据结构 线性表的实现代码(C语言)可直接运行_数据结构的代码用什么软件运行-程序员宅基地

技术标签: 数据结构  

这是我在大二学习数据结构中的代码实践,将《数据结构》(严蔚敏)中的伪代码用C语言实现。

本人水平有限,难免存在一些错误,欢迎各位同学批评指正。如果这篇文章对您有所帮助,请留下一个赞吧,谢谢!


目录

顺序实现(动态数组)

 

链式实现(单向链表)


顺序实现(动态数组)

代码如下:

/* 线性表的顺序实现 */
/* Note
  	(1) 优点
        a.节省存储空间;
        b.对线性表中第i个结点的操作易于实现;
        c.容易查找一个结点的前驱和后继。
	(2)缺点
        a.插入和删除操作需要移动数据;
        b.建立空表时,较难确定所需的存储空间。
*/

#include<stdio.h>
#include<stdlib.h>
#define LIST_INIT_SIZE 100 	// 线性表存储空间的初始分配量
#define LISTINCERMENT 10	// 线性表存储空间的分配增量
#define ElemType int
#define ERROR 0

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

void InitList_Sq(SqList* L)
{
	L->elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
	if(!L->elem) exit(ERROR);
	L->length = 0;
	L->listsize = LIST_INIT_SIZE;
	return;
}


void DestroyList_Sq(SqList* L)
{
	free(L->elem);
	return;
}

void GetElem_Sq(SqList L, int i, ElemType* e)
{
	// SqList中第i个位置的元素是elem[i-1]
	*e = L.elem[i-1];
	return;
}

void ListInsert_Sq(SqList* L, int i, ElemType e)
{
	// 先判断插入位置是否正确
	if(i > L->length+1 || i < 1)  exit(ERROR);
	
	// 再判断是否表满
	if(L->length == L->listsize)
	{
		// 如果表满,则新分配一个更大的内存
		ElemType* newbase = (ElemType *)realloc( L->elem, (L->listsize + LISTINCERMENT)*sizeof(ElemType));
		if(!newbase) exit(ERROR);
		
		// 基地址指向新的内存		
		L->elem = newbase;
		
		// 新的顺序表内存大小
		L->listsize += LISTINCERMENT;
	}
	
	// 从最后一个元素的下一个位置开始,将插入位置及之后的元素向后滑动一位
	for(int j = L->length; j >= i; j--)
	{
		L->elem[j] = L->elem[j-1];
	}
	
	// 此时第i个位置空出,插入元素e
	L->elem[i-1] = e;
	++ L->length;
	return;
}

void ListDelete_Sq(SqList* L, int i, ElemType* e)
{
	// 先判断顺序表是否为空
	if(L->length == 0) exit(ERROR);
	
	// 再判断删除位置是否正确
	if(i < 1 || i > L->length) exit(ERROR);
	
	// 将待删除位置的元素取出
	*e = L->elem[i-1];
	for(i; i<L->length ; ++i)
	{
		L->elem[i-1] = L->elem[i];
	}
	--L->length;
	return;
}

void ListTraverse_Sq(SqList L)
{
	for(int i=0; i<L.length; ++i)
	{
		printf("%d ",L.elem[i]);
	}
	return;
}

void menu()
{
	printf("-------------------------------------\n");
	printf("1、初始化顺序表        2、销毁顺序表\n");
	printf("3、插入元素            4、删除元素\n");
	printf("0、退出\n");
	printf("-------------------------------------\n");
}


int main()
{
	SqList L;
	while(true)
	{
		menu();
		int choice;
		scanf("%d",&choice);
		switch(choice)
		{
		case 1:
			InitList_Sq(&L);
			break;
		case 2:
			DestroyList_Sq(&L);
			break;
		case 3:
			{
				int i;
				printf("请输入要插入的位置:");
				scanf("%d",&i);
	
				ElemType e;
				printf("请输入要插入的元素:");
				scanf("%d",&e);
	
				ListInsert_Sq(&L, i, e);
				printf("当前顺序表:");
				ListTraverse_Sq(L);
				printf("\n");
				break;
			}
		case 4:
			{
				int i;
				printf("请输入要删除的位置:");
				scanf("%d",&i);
	
				ElemType e;
				ListDelete_Sq(&L, i, &e);
				printf("当前顺序表:");
				ListTraverse_Sq(L);
				printf("\n");
				break;
			}
		case 0:
			{
				DestroyList_Sq(&L);
				return 0;
			}
		}
	}
}

 


链式实现(单向链表)

代码如下:

/* 线性表的链式实现 */
/* Note
  	(1) 优点
        a. 插入和删除不需要移动数据(时间复杂性低);
        b.不需预先分配空间。
    (2)缺点
        a.指针占用存储空间,增加了内存负担。
        b.只能顺序查找(操作)。
*/
#include<stdio.h>
#include<stdlib.h>
#define ERROR 0
#define ElemType int

typedef struct LNode
{
	ElemType data;
	struct LNode* next;
} LNode, * LinkList;


// 初始化一个带头结点的空链表L
LinkList InitList_L()
{
	// 构造一个头结点L
	static LinkList L;
	L = (LNode*)malloc(sizeof(LNode));
	if(!L) exit(ERROR);

	// 让L的数据域存储链表的长度信息
	L->data = 0;
	L->next = NULL;

	return L;
}


// 生成一个含有n个结点的链表
LinkList CreateList_L(int n)
{
	// 建立头结点L
	static LinkList L;
	L = (LNode*)malloc(sizeof(LNode));
	if(!L) exit(ERROR);
	L->data = n;
	L->next = NULL;
	// 尾指针 用于尾插法 
	LinkList rear = L;

	for(int i = 0; i < n; ++i)
	{
		// 建立新的结点p
		LinkList p = (LNode*)malloc(sizeof(LNode));
		if(!p) exit(ERROR);
		scanf("%d",&p->data);

		// 尾插法
		p->next = NULL;
		rear->next = p;
		rear = p; 
	}
	return L;
}


void DestroyList_L(LinkList L)
{
	LinkList p = L;
	while(p)
	{
		p = p->next;
		free(L);
		L = p;
	}
}


void ListInsert_L(LinkList L, int i, ElemType e)
{
	// 在带头结点的单链线性表L中第i个位置之前插入元素e

	// 指针p指向头结点L
	LinkList p = L;

	// 判断插入位置是否正确
	if(i > L->data+1 || i < 1)  exit(ERROR);

	// 寻找第i-1个结点
	for(int j = 0; j < i-1; ++j)
	{
		p = p->next;
	}

	// 插入新结点S
	LinkList S;
	S = (LNode*)malloc(sizeof(LNode));
	if(!S) exit(ERROR);
	S->data = e;
	S->next = p->next;
	p->next = S;

	// 链表长度+1
	++ L->data;

	return;
}


void ListDelete_L(LinkList L, int i, ElemType* e)
{
	// 先判断删除的位置是否正确
	if(i < 1 || i > L->data) exit(ERROR);

	// 指针p指向头结点L
	LinkList p = L;

	// 找到第i-1个结点
	for(int j = 0; j < i-1; ++j)
	{
		p = p->next;
	}

	// 指针q指向第i个元素
	LinkList q = p->next;
	*e = q->data;
	p->next = q->next;
	free(q);

	// 链表长度减1
	-- L->data;
}

void ListTraverse_L(LinkList L)
{
	LinkList p = L->next;
	while(p)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	return;
}


void menu()
{
	printf("----------------------------------------------\n");
	printf("1、初始化带头节点链表  2、创建含n个元素的链表\n");
	printf("3、插入结点            4、删除节点\n");
	printf("0、销毁链表并退出\n");
	printf("----------------------------------------------\n");
}



int main()
{
	static LinkList L;
	while(true)
	{
		menu();
		int choice;
		scanf("%d",&choice);
		switch(choice)
		{
			case 1:
				{
					L = InitList_L();
					break;
				}
			case 2:
				{
					int n;
					printf("请输入链表长度:");
					scanf("%d",&n);

					printf("请输入n个节点的数据(用空格分开):");
					L = CreateList_L(n);
					ListTraverse_L(L);
					printf("\n");
					break;
				}
			case 3:
				{
					int i;
					printf("请输入要插入的位置:");
					scanf("%d",&i);

					ElemType e;
					printf("请输入要插入的元素:");
					scanf("%d",&e);

					ListInsert_L(L, i, e);
					ListTraverse_L(L);
					printf("\n");
					break;
				}
			case 4:
				{
					int i;
					printf("请输入要删除的位置:");
					scanf("%d",&i);

					ElemType e;

					ListDelete_L(L, i, &e);
					ListTraverse_L(L);
					printf("\n");
					break;
				}
			case 0:
				{
					DestroyList_L(L);				
					return 0;
				}
		}
	}
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/HiterNza/article/details/108997951

智能推荐

华为Ebackup备份系统安装-程序员宅基地

文章浏览阅读603次,点赞10次,收藏11次。开始我觉的也不错,但是作为强迫症后期患者,我还是想将Ebackup独立部署,问题出来了,我暂时还没有兼容Ebackup服务器的硬件服务器(这里得注意,如果将Ebackup部署在裸金属上,兼容性得好好确认下,不然驱动啥的很麻烦),最后好好想了想,还是装个ESXI吧,把Ebackup和NAS部署上去。如果没有FusionCompute的授权,也不用担心,你可以使用基础版,直接使用就行,90天的试用期,过了之后自动转换成基础版,虽然是基础版,功能也够用了。这个我会随后的文章中贴出来,很简单,自己百度下也行。

简单解决android EditText需要点击两下才响应点击事件_android edittext 点击第二次才能唤起输入法-程序员宅基地

文章浏览阅读5.6k次,点赞4次,收藏5次。功能:实现点击EditText弹出三级联动选择器,添加了OnClickListener监听,但是每次需要点击两下才能弹出选择器,其实第一次是获取了输入框的焦点解决办法:在布局文件中给EditText添加android:focusable="false",不过这样输入框就不能编辑了如下:<EditText android:layout_width="match_paren..._android edittext 点击第二次才能唤起输入法

Cocos2d-x 手游聊天系统Demo实现(Lua实现)(1)-程序员宅基地

文章浏览阅读590次,点赞19次,收藏10次。其实很简单就下面这张图,含概了Android所有需要学的知识点,一共8大板块:架构师筑基必备技能Android框架体系架构(高级UI+FrameWork源码)360°Androidapp全方位性能调优设计思想解读开源框架NDK模块开发移动架构师专题项目实战环节移动架构师不可不学习微信小程序混合开发的flutterAndroid学习的资料我呢,把上面八大板块的分支都系统的做了一份学习系统的资料和视频,大概就下面这些,我就不全部写出来了,不然太长了影响大家的阅读。

Debian6.0 linux安装redmine-程序员宅基地

文章浏览阅读59次。参照:http://hi.baidu.com/guoqs/item/f05177e733ca0f3c4ddcafa01.安装ruby相关apt-get install ruby1.9.1apt-get install rakeapt-get install rubygemsapt-get install rakegem install bundler2.安装..._debian6.0 的管理员用户名是啥

Juniper EX系列交换机堆叠配置-程序员宅基地

文章浏览阅读1.8k次。set version 12.3R6.6set groups member0 system host-name SHGYAS_SW_VC_01set groups member1 system host-name SHGYAS_SW_VC_02set apply-groups member0set apply-groups member1set system time-zo..._juniper ex4300 堆叠 delete

PHP 异常处理:Exception 类的使用技巧_php 原生代码中exception类-程序员宅基地

文章浏览阅读21次。通过遵循这些技巧和最佳实践,我们可以更好地使用PHP的Exception类来处理异常,提高代码的可靠性和可维护性。这些最佳实践包括只捕获需要处理的异常类型、提供有用的错误信息、在适当的地方抛出异常以及使用合理的异常类层次结构。Exception 类是 PHP 内置的基础异常类,我们可以通过继承 Exception 类创建自定义的异常类。在实际开发中,我们可能会遇到多种不同类型的异常,针对不同类型的异常,我们可以使用多个。在实际开发中,可能会遇到多种不同类型的异常,针对不同类型的异常,可以使用多个。_php 原生代码中exception类

随便推点

从Matlab实例学习蚁群算法(2)_蚂蚁算法求最小值-程序员宅基地

文章浏览阅读2.1k次。在中我们介绍了用蚁群算法求解TSP问题的实例。进一步的,本文介绍一个通过蚁群算法求解连续问题的实例。_蚂蚁算法求最小值

领域模型驱动设计简介_领域模型创新点-程序员宅基地

文章浏览阅读1.1k次。1 简介领域驱动设计告诉我们,在通过软件实现一个业务系统时,建立一个领域模型是非常重要和必要的,因为领域模型具有以下特点:领域模型是对具有某个边界的领域的一个抽象,反映了领域内用户业务需求的本质;领域模型是有边界的,只反应了我们在领域内所关注的部分; 领域模型只反映业务,和任何技术实现无关;领域模型不仅能反映领域中的一些实体概念,如货物,书本,应聘记录,地址,等;还能反映领域中的一些过程..._领域模型创新点

二极管、三极管、场效应管的原理及特性_二极管 三极管-程序员宅基地

文章浏览阅读1.5w次,点赞22次,收藏131次。本文组要摘出了二极管、三极管、场效应管的原理及特性。主要目的是梳理它们的结构及原理,由于细细写来信息量还是蛮大的,所以难免会会有信息的丢失,但大体的结构是完整的。;-)一、半导体二极管 定义:奖PN结用外壳封装起来,并加上电机引线就构成了半导体二极管。 常见的二极管类型如图(1)图(1)普通二极管,主要是利用它正向导通,反向截止的特性(单向导电性)。_二极管 三极管

C语言学习笔记_c语言 x<y<z-程序员宅基地

文章浏览阅读496次。数据常量大分类字面常量: 直观写出来的值 const修饰发常量 #define定义的常量 枚举常量常量,const常变量int main(){ const int num = 1;\\const 表示常属性变量的创建 num = 8; return 0;}​是不能运行的int main(){ const int n = 4; printf("%d\n", n); int arr[n] = { 0 }; r_c语言 x

Petya勒索病毒-程序员宅基地

文章浏览阅读1.2w次。Petya勒索病毒1、原理说明2017年6月27日晚,印度、俄罗斯、西班牙以及欧洲多国遭受大规模Petya勒索病毒袭击,该病毒远程锁定设备,并索要赎金。其中乌克兰地区受灾害最为严重,政府、银行、电力系统、通讯系统、企业等都受到不同程度的影响。此次攻击者采用早前Petya勒索病毒的变种,其传播方式和WannaCry类似,但该病毒除了使用永恒之蓝(MS17-010)漏洞之外,还罕见使用了黑客的横向渗透攻击技术。在勒索方面与WannaCry等不同之处在于,Petya木马主要通过加密硬盘驱动器主文件表(_petya

petapoco mysql_PetaPoco - 轻量级高性能的ORM框架(支持.NET Core)-程序员宅基地

文章浏览阅读332次。我们都知道ORM全称叫做Object Relationship Mapper,也就是可以用object来map我们的db。而且市面上的orm框架有很多,有重量级的Entity Framework,有轻量级的Dapper、PetaPoco等假如你喜欢原生的Sql语句、又喜欢ORM的简单、又追求高性能,那么轻量级的ORM框架是你的不二选择。说到轻量级ORM框架Dapper的名气比较大(因为出自名门?)..._petapoco