【考研】数据结构(更新到双链表)

声明:所有代码都可以运行,可以直接粘贴运行(只有库函数没有声明)

线性表的定义和基本操作

基本操作

  1. 定义
    静态:
#include<stdio.h>
#include<stdlib.h>

#define MaxSize 10

//静态 
typedef struct{
	int data[MaxSize];
	int length;
}SqList;

void InitList(SqList &L)//初始化 
{
	for(int i=0;i<MaxSize;i++){
		L.data[i]=0;
	}
    L.length=0;
}

int main(void)
{
	SqList L;
	InitList(L);
	
	for(int i=0;i<L.length;i++){
		printf("the data %d is %d",i,L.data[i]);
	}
	
	return 0;
}

动态:

#include<stdio.h>
#include<stdlib.h>

#define InitSize 10

typedef struct{
	int *data;
	int MaxSize;//最大容量 
	int length;//当前长度 
}SeqList;

void Init(SeqList &L)
{
	L.data=(int *)malloc(InitSize*sizeof(int));
	L.length=0;
	L.MaxSize=InitSize;
}

int main(void){
	
	return 0;
}
  1. 插入
    静态:
//插入操作,bool用于判断操作是否成功 (处理异常情况) 
bool ListInsert(SqList &L,int i,int e){
	if(i<1 || i>L.length+1) return false;//条件判断 
	if(L.length >= MaxSize) return false;
	
	for(int j=L.length;j>=i;i--){
		L.data[j]=L.data[j-1];
	}
	L.data[i-1]=e;
	L.length++;
}

在这里插入图片描述
动态:


  1. 删除
    静态:
bool ListDelete(SqList &L,int i,int &e){
	if(i<1||i>L.length) return false;
	e=L.data[i-1];
	for(int j=i;j<L.length;j++)
	{
		L.data[j-1]=L.data[j];
	}
	L.length--;
	return true;
}

动态顺序表以及各个操作

#include<stdio.h>
#include<stdlib.h>
#define InitSize 10

typedef struct{
	int *data;
	int MaxSize;
	int length;
}SqList;

void debug(SqList L){
	printf("当前顺序表的数据为length=%d maxsize=%d\n",L.length,L.MaxSize);
}
//初始化
void InitList(SqList &L){
	L.data=(int *)malloc(InitSize*sizeof(int));
	L.length=0;
	L.MaxSize=InitSize;
}
 
//增加动态数组的长度
void IncreaseSize(SqList &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;//顺序表最大长度增加len 
	free(p);//释放空间		
} 

//插入操作
bool ListInsert(SqList &L,int i,int e){
	//范围判断 
	if(i<1 || i>L.length+1)
		return false;
	if(L.length>L.MaxSize)
	return false;
	
	for(int j=L.length;j>=i;j--)
	{
		L.data[j]=L.data[j-1];
	}
	L.data[i-1]=e;
	L.length++;
	return true;
} 

删除操作,删除第i个数据并且返回被删除的数据 
bool ListDelete(SqList &L,int i,int &e)
{
	//范围判断
	 if(i<1 || i>L.length+1) return false;
	 else{
	 	//保存删除元素
		 e=L.data[i]; 
	 	for(int j=i;j<L.length;j++)
	 	{
		 L.data[j]=L.data[j+1];
	    }
	    L.length--;
	 } 
	 return true;
 } 

//按位查找
int getElemBybit(SqList L,int i){
	//Check if the line has been crossed
	if(i<1 || i>L.length){
		printf("Cross the border!");
		return 0;
	}
	
	return L.data[i-1];
} 

//按值查找
int getElemByValue(SqList L,int value){
	for(int i=0;i<L.length;i++)
	{
		if(L.data[i] == value)
		{
			return i-1;
		}
	}
	printf("Can`t find the elem!");
	
	return 0;
} 

//打印操作
void print(SqList L){
	for(int i=0;i<L.length;i++)
	{
		printf("%d ",L.data[i]);
	}
	printf("\n");
} 

//测试函数 
int main(void){
	SqList L;debug(L);
	InitList(L);debug(L);
	
	for(int i=0;i<L.MaxSize;i++)
	{
		L.data[i]=i;
	    L.length++;
	}
	IncreaseSize(L,5);debug(L);
	
	print(L);
	if(ListInsert(L,2,5)){
	printf("插入成功,插入后数值");
		print(L);
	}else printf("插入失败");
	
	int e=0;
	if(ListDelete(L,3,e))
	{
		print(L);
		printf("被删除元素为:%d",e);
	}

    int value,position;
	printf("\nPlease input the value and the position:");  
    scanf("%d %d", &value, &position);  
	printf("\nget the emlem by value :the elem position is%d\n",getElemByValue(L,value));
	printf("\nget the emlem by positon:the value is%d\n",getElemBybit(L,position));
	
	return 0;
}

链表基本

链表结构:
单链表:

//定义单链表
typedef struct LNode {
	int data;           // 数据域 
	struct LNode* next; // 指针域 
} LNode, * LinkList;

双链表:

//定义结构
typedef struct DNode{
	int data;//数据域 
	struct DNode *prior,*next;//指针域 
}DNode,*DLinkList;

单链表

操作:

// 初始化一个链表,带头结点
bool InitList(LinkList* L);

// 按照位序插入
bool ListInsert(LinkList* L, int i, int e);

// 指定结点的后插操作
bool InsertNextNode(LNode* p, int e);

// 指定结点的前插操作
bool InsertPriorNode(LNode* p, int e);

// 按位序删除结点
bool ListDelete(LinkList* L, int i, int* e);

// 创建方式 - 头插法创建
LinkList List_HeadInsert(LinkList* L);

//创建方法 - 尾插法创建
LinkList List_TailInsert(LinkList* L);

//指定结点的删除
bool DeleteNode(LNode *p);

//按位查找
LNode *GetElem(LinkList L,int i);

//按值查找
LNode *LocateElem(LinkeList L,int e); 

//求单链表的长度
int length(LinkList L);

//链表逆置
LNode *Inverse(LNode *L); 

// 打印链表
void print(LinkList L); 

操作实现:

// 打印链表
void print(LinkList L) {
	LinkList E = L->next;

	while (E != NULL) {
		printf("%d ", E->data);
		E = E->next;
	}
	printf("\n");
}

// 初始化一个链表,带头结点
bool InitList(LinkList* L) {
	*L = (LNode*)malloc(sizeof(LNode));

	if (*L == NULL) return false;
	(*L)->next = NULL;
	printf("Initialization of the linked list succeeded!\n");
	return true;
}

// 按照位序插入
bool ListInsert(LinkList* L, int i, int e) {
	if (i < 1) return false; // 判断操作合法

	LNode* p = *L;
	int j = 0;
	while (p != NULL && j < i - 1) {
		p = p->next;
		j++;
	}
     
    int choice =0;
    printf("Prior or next?(1/2)");
    scanf("%d",&choice);
    if(choice == 2)
	return InsertNextNode(p, e);
	if(choice == 1)
	return InsertPriorNode(p,e);
	else
	return false;
}

// 指定结点的后插操作 
bool InsertNextNode(LNode* p, int e) {
	if (p == NULL) return false; // 判断合法 

	LNode* s = (LNode*)malloc(sizeof(LNode));
	if (s == NULL) return false; // 内存分配失败 

	s->data = e;
	s->next = p->next;
	p->next = s;

	return true;
}

// 指定结点的前插操作
bool InsertPriorNode(LNode* p, int e) {
	if (p == NULL) return false;

	LNode* s = (LNode*)malloc(sizeof(LNode));
	if (s == NULL) return false;

	s->next = p->next;
	p->next = s;
	s->data = p->data; // 交换数值从而实现前插操作,方法还是后插的方法 
	p->data = e;

	return true;
}

// 按位序删除结点并返回删除数据 
bool ListDelete(LinkList* L, int i, int* e) {
	if (i < 1) return false; // 判断操作合法

	LNode* p = *L;
	int j = 0;

	while (p != NULL && j < i - 1) {
		p = p->next;
		j++;
	} // 定位到删除结点
	if (p == NULL) return false;
	if (p->next == NULL) return false;

	LNode* q = p->next;
	*e = q->data;
	p->next = q->next;
	free(q);

	return true;
}


// 创建方式
// 1. 头插法创建 O(n)
LinkList List_HeadInsert(LinkList* L) {
	*L = (LinkList)malloc(sizeof(LNode)); // 建立头结点
	(*L)->next = NULL;                    // 初始为空链表,这步不能少!

	int x;
	LNode* s;
	printf("input the x:");
	scanf("%d", &x);
	while (x != 9999) {
		s = (LNode*)malloc(sizeof(LNode));
		s->data = x;
		s->next = (*L)->next;
		(*L)->next = s;
		printf("Continue input the x:");
		scanf("%d", &x);
	}
	return *L;
}

//指定结点的删除(重点理解) 
bool DeleteNode(LNode *p){
	if(p == NULL) return false;
	
	LNode *q=p->next;
	p->data=p->next->data;
	p->next=q->next;
	free(q);
	
	return true;
}

//按位查找
LNode *GetElem(LinkList L,int i){
	if(i<1) return false;
	
	LNode *p=L->next;
	int j;
	while(p!=NULL && j<i-1){
		p=p->next;
		j++;
	}
	return p;
}

//按值查找
LNode *LocateElem(LinkList L,int e){
	if(L == NULL) return false;
	
	LNode *p=L->next;
	while(p != NULL && p->data!=e){
		p=p->next;		
	}
	return p;
}

//求单链表的长度
int length(LinkList L){
	int len=0;
	LNode *p=L;
	
	while(p->next!=NULL)
	{
		p=p->next;
		len++;
	}
	
	return len;
} 

//创建方法 - 尾插法创建
//创建方法 - 尾插法创建
LinkList List_TailInsert(LinkList* L){
	int x;
	*L=(LinkList)malloc(sizeof(LNode));
	LNode *s,*r=*L;
	
	printf("输入插入的结点的值:");
	scanf("%d",&x);
	while(x != 9999){
		s=(LNode *)malloc(sizeof(LNode));
		s->data=x;
		r->next=s;
		r=s;
		scanf("%d",&x);
	}
	r->next=NULL;
	
	return *L;
}

//链表逆置(重点理解) 
LNode *Inverse(LNode *L){
	LNode *p,*q;
	p=L->next;
	L->next=NULL;
	
	while(p!=NULL){
		q=p;
		p=p->next;
		q->next=L->next;
		L->next=q;
	}
	
	return L;
}

测试代码

int main(void) {
	LinkList L = NULL;
	LNode *elem = NULL;
	int e=0;
	
	List_HeadInsert(&L);print(L);
	printf("Insert:\n");
	ListInsert(&L,2,3);	print(L);
	ListDelete(&L,3,&e);print(L);
	printf("Deleted elem:%d\n",e);
	printf("Delete the elem by Node\n");
	DeleteNode(L->next->next);print(L);
	printf("Search by position\n");
	elem=GetElem(L,3);printf("the elem is:%d\n",elem->data);
	printf("Inverse the Link\n");
	L=Inverse(L);print(L);
	
	return 0;
}

双链表

操作:

//打印 
void print(DLinkList L);
//链表的初始化 ,
bool InitLinkList(DLinkList *L);
//判空
bool isEmpty(DLinkList L); 
//后插操作,将s插入p之后 
bool InsertNextNode(DNode *p,DNode *s); 
//前插操作
bool InsertPriorNode(DNode *p,DNode *s); 

定义:

bool InitLinkList(DLinkList *L){
	*L = (DNode *)malloc(sizeof(DNode));
	if(L == NULL) return false;
	
	(*L)->next=NULL;
	(*L)->prior=NULL;
	return true; 
}

bool isEmpty(DLinkList L){
	if(L->next==NULL) return true;
	else
 		return false;
}
 
bool InsertNextNode(DNode *p,DNode *s){
	if(p==NULL || s==NULL){
		printf("非法\n");return false;
	}
	
	s->next=p->next;
	s->prior=p;
	p->next=s;
	
	printf("Insert next node success!\n");
	return true;
}

bool InsertPriorNode(DNode *p,DNode *s){
	if(p==NULL || s==NULL || p->prior==NULL){
		printf("非法\n");return false;
	}
	
	s->prior=p->prior;
	s->next=p;
	p->prior=s;
	
	
	printf("Insert prior node success!\n");
	return true;
}

void print(DLinkList L){
	L=L->next;//因为有头结点 
	while(L!=NULL)
	{
		printf("%d ",L->data);
		L=L->next;
	}
}

测试:

//测试 
int main(void){
    
	DLinkList L;
	DNode *node;
	int data,x;
		
	if(InitLinkList(&L)){
		printf("初始化成功!");	
	}
	printf("开始插入(9999停止)\n");
	scanf("%d",&x);
	while(x !=9999){
		node=(DNode *)malloc(sizeof(DNode));
		node->data=x;
		InsertNextNode(L,node);
		scanf(" %d",&x);
	}
	print(L);
  	
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/175735.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NEJM一篇新文为例,聊聊孟德尔随机化研究mr

2019年3月14日&#xff0c;新英格兰医学杂志发表了一篇论著&#xff0c;Mendelian Randomization Study of ACLY and Cardiovascular disease, 即《ACLY和心血管疾病的孟德尔随机化研究》。与小咖在2017年1月9日报道的一篇发表在新英格兰医学的孟德尔随机化研究——精读NEJM&am…

2023年中国工业炉分类、产量及市场规模分析[图]

工业炉是指在工业生产中利用燃料燃烧或电能等转换产生的热量&#xff0c;将物料或工件进行熔炼、熔化、焙&#xff08;煅&#xff09;烧、加热、干馏、气化等的热工设备&#xff1b;广泛应用于机械、冶金、化工及陶瓷等国民经济的各行各业&#xff0c;具有生产效率高、产品质量…

又3本“On Hold”期刊被剔除!这本Elsevier旗下中科院2区TOP仍在调查中!

【SciencePub学术】 此前&#xff0c;继又2本期刊被“On Hold”&#xff01;标识后&#xff0c;仍处于“On Hold”状态的期刊有8本&#xff0c;其中包括4本SCI期刊和4本ESCI期刊。 2023年11月20日&#xff0c;科睿唯安更新了Web of Science核心期刊目录。 本次11月更新共64本期…

向量数据库,展望AGI时代

无论是向量数据库&#xff0c;还是大模型&#xff0c;归根结底&#xff0c;大家在追捧它时的心态&#xff0c;焦虑大于需求。 向量数据库的热潮&#xff0c;在一定程度上“外化”了人们的焦虑。 但这并不能否定向量数据库的实际价值&#xff0c;甚至更长远来看&#xff0c;向…

Vue3实现粒子动态背景

官网&#xff1a; https://particles.js.org/ npm&#xff1a; https://www.npmjs.com/package/particles.vue3 安装 pnpm add particles.vue3 pnpm add tsparticles-slim 引入使用&#xff0c;完整代码 <template><div class"wft-particles-container&quo…

vue超好用的自定义指令封装

一、指令封装 目录结构&#xff1a; index.ts 统一注册 import { App, Directive } from "vue"; import auth from "./modules/auth"; import copy from "./modules/copy"; import waterMarker from "./modules/waterMarker"; impor…

Springboot企业网站 毕业设计-附源码73192

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

人工智能中的文本分类:技术突破与实战指导

在本文中&#xff0c;我们全面探讨了文本分类技术的发展历程、基本原理、关键技术、深度学习的应用&#xff0c;以及从RNN到Transformer的技术演进。文章详细介绍了各种模型的原理和实战应用&#xff0c;旨在提供对文本分类技术深入理解的全面视角。 关注TechLead&#xff0c;分…

API之 要求接口上传pdf 以 合同PDF的二进制数据,multpart方式上传

实现 //时间戳13位毫秒private function getMillisecond() {list($s1,$s2) explode( ,microtime());return (float)sprintf(%.0f,(floatval($s1) floatval($s2)) * 1000);}// 组装参数private function gysscPost1($url,$data){// $data[timestamp] 1694402111964;$data[tim…

主播产品话术

以电子产品为例 一、产品特点 1.高效性能:这款产品采用了最先进的技术&#xff0c;确保高效运行&#xff0c;让你的工作更加流畅。 2.便捷操作:设计简洁&#xff0c;操作方便&#xff0c;即使是不熟悉电子产品的人也能轻松上手。 3.时尚外观:多种颜色可选&#xff0c;满足你…

2023年中国离心制冷机产量及产业链分析[图]

离心制冷机是一种常用的空调制冷设备&#xff0c;目前主要应用于酒店、写字楼、商场、学校等众多大型场所的集中制冷场景。离心制冷机由离心式制冷压缩机、蒸发器、冷凝器、主电动机、抽气回收装置、润滑系统、控制柜和起动柜等零部件组成。这些零部件的组成有的采用分散型组装…

不看后悔系列 | 秒做BI报表,告别低效分析

根据经验来看&#xff0c;做企业数据分析&#xff0c;通常是由业务提出需求&#xff0c;交给IT去取数开发&#xff0c;当业务通过分析报表有了新的需求时&#xff0c;仍需交给IT去取数分析&#xff0c;这就导致业务的分析效率低。进入大数据时代&#xff0c;这样的低效数据分析…

wpf使用CefSharp.OffScreen模拟网页登录,并获取身份cookie

目录 框架信息&#xff1a;MainWindow.xamlMainWindow.xaml.cs爬取逻辑模拟登录拦截请求Cookie获取 CookieVisitorHandle 框架信息&#xff1a; CefSharp.OffScreen.NETCore 119.1.20 MainWindow.xaml <Window x:Class"Wpf_CHZC_Img_Identy_ApiDataGet.MainWindow&qu…

ASM字节码操作类库(打开java语言世界通往字节码世界的大门) | 京东云技术团队

前言&#xff1a;授人以鱼不如授人以渔&#xff0c;应用asm的文章有很多&#xff0c;简单demo的也很多&#xff0c;那么ASM都具备哪些能力呢&#xff1f;如何去学习编写ASM代码呢&#xff1f;什么样的情景需要用到ASM呢&#xff1f;让我们带着这些问题阅读这篇文章吧。 这里由…

功率放大器在无线收发系统中的作用

功率放大器在无线收发系统中也扮演着至关重要的角色。无线通信是一种通过电磁波传输信息的技术&#xff0c;它具有便捷、灵活、广覆盖等优势&#xff0c;在现代社会得到了广泛应用。而功率放大器则是无线收发系统中的核心组件之一&#xff0c;主要用于增强信号的功率和距离。下…

paramiko STELNET登陆设备

实验目的&#xff1a; 公司有一台CE12800的设备&#xff0c;管理地址位172.16.1.2&#xff0c;现在需要编写自动化脚本&#xff0c;通过ssh登陆到设备上并进行简单的信息查看。 实验拓扑&#xff1a; 实验步骤&#xff1a; 步骤1&#xff1a;将本地电脑和ensp的设备进行桥接…

振南技术干货集:制冷设备大型IoT监测项目研发纪实(2)

注解目录 1.制冷设备的监测迫在眉睫 1.1 冷食的利润贡献 1.2 冷设监测系统的困难 &#xff08;制冷设备对于便利店为何如何重要&#xff1f;了解一下你所不知道的便利店和新零售行业。关于电力线载波通信的论战。&#xff09; 2、电路设计 2.1 防护电路 2.1.1 强电防护 …

HT5169 单声道D类音频功放 I2S输入

HT5169是一款内置BOOST升压模块的D类音频功率放大器。内置的BOOST升压模块可通过外置电阻调节升压值&#xff0c;即使是锂电池供电&#xff0c;在升压至7.5V&#xff0c;2Ω负载条件下则能连续输出 11W功率。其支持外部设置调节BOOST输出电压。 HT5169是一颗单声道D类音频功放&…

银河麒麟安装Docker

# 配置阿里云 Centos8 镜像源&#xff0c;需要额外的一些依赖&#xff0c;而这些依赖在麒麟官方的源里面是没有的 sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo# 配置阿里云 docker 镜像源 sudo yum-config-manager --add-r…