首页 > 其他分享 >数据结构练习-C语言

数据结构练习-C语言

时间:2024-03-24 22:29:16浏览次数:26  
标签:结点 LN top 练习 C语言 int 数据结构 data 方块

1.假设有一个带头结点的单链表 L ,每个结点值由单个数字、小写字母和大写字母构成。设计一个算法将其拆分成3个带头结点的单链表L1、L2和L3,L1包含 L 中的所有数字结点,L2包含 L 中的所有小写字母结点,L3包含 L 中的所有大写字母结点。该算法如何设计?

首先创建L1、L2、L3的头结点,然后利用if判断语句将L的单个数字、小写字母和大写字母分配到L1、L2、L3,可以利用尾插法进行分配,最后用建立项目对其验证。

#include<stdio.h>
#include<malloc.h>
//链表结构
typedef struct LNode {
	char data;
	struct LNode* next;
}LN;
//创建链表L
void Create_L(LN*& L, char a[], int n) {
	int i;
	LN* d, * w;
	//建立头结点
	L = (LN*)malloc(sizeof(LN));
	w = L;	//w始终指向尾结点,开始时指向头结点
	//传送数据
	for (i = 0; i < n; i++) {
		d = (LN*)malloc(sizeof(LN));
		d->data = a[i];	//创建数据结点d

		w->next = d;
		w = d;	//尾插法
	}
	w->next = NULL;	//使尾结点next域为NULL
}
//将L分为只含数字、小写字母、大写字母的3个L1、L2、L3
void L123(LN* L, LN*& L1, LN*& L2, LN*& L3) {
	LN* p = L->next, * a, * b, * c, * x, * y, * z;
	//建立头结点
	L1 = (LN*)malloc(sizeof(LN));
	L2 = (LN*)malloc(sizeof(LN));
	L3 = (LN*)malloc(sizeof(LN));
	//x,y,z始终指向尾结点,开始时指向头结点
	x = L1;
	y = L2;
	z = L3;

	while (p != NULL) {
		//判断数据,进行分配
		if (p->data >= '0' && p->data <= '9') {
			a = (LN*)malloc(sizeof(LN));
			a->data = p->data;	//创建数据结点a

			x->next = a;
			x = a;	//尾插法
		}
		else if (p->data >= 'a' && p->data <= 'z') {
			b = (LN*)malloc(sizeof(LN));
			b->data = p->data;	//创建数据结点b

			y->next = b;
			y = b;	//尾插法
		}
		else if (p->data >= 'A' && p->data <= 'Z') {
			c = (LN*)malloc(sizeof(LN));
			c->data = p->data;	//创建数据结点c

			z->next = c;
			z = c;	//尾插法
		}
		else
			printf("错误");

		p = p->next;
	}
	//使尾结点next域为NULL,结束分配
	x->next = NULL;
	y->next = NULL;
	z->next = NULL;
}
//显示链表
void Display_L(LN* L) {
	LN* p = L->next;
	while (p != NULL) {
		printf("%c ", p->data);
		p = p->next;
	}
	printf("\b\n");
}
//主函数,执行任务
int main() {
	LN* L, * L1, * L2, * L3;
	//开始创建L
	char a[9] = { '3','d','G','A','9','c','K','W','4' };
	Create_L(L, a, 9);
	//将L分为只含数字、小写字母、大写字母的3个L1、L2、L3
	L123(L, L1, L2, L3);
	//显示L,L1,L2,L3
	Display_L(L);
	Display_L(L1);
	Display_L(L2);
	Display_L(L3);
}

2.二叉树的顺序存储结构和二叉链存储结构各有什么优缺点

(1)二叉树的顺序存储结构是将完全二叉树从上到下、从左到右按顺序存储。

①优点:自带元素之间的逻辑关系,方便查找双亲和孩子。

②缺点:在存储非完全二叉树的时候空间利用率低。

(2)二叉链存储结构是由数据域和左右指针域组成,左、右指针分别指向该结点左孩子和右孩子所在的链结点的存储地址。

①优点:知道某结点就知道其左孩子和右孩子;存储利用率高。

②缺点:查找指定结点效率低;包含指针,存储密度小。

3.假设二叉树采用二叉链存储结构,设计一个算法输出从根结点到某个叶子结点的路径逆序列。(遍历算法不限)。

采用后序遍历非递归算法:

①先沿着根结点依次入栈,分配左孩子直到其为空;

②取栈顶元素。若右孩子非空且未被访问过,将右子树转执行①;否则,栈顶元素出栈并访问。

#include<stdio.h>
#include<malloc.h>
//二叉树采用二叉链存储结构
typedef struct BLnode {
	char data;
	struct BLnode *lchild;
	struct BLnode *rchild;
}BLnode,*BT;
//创建二叉树
void Create_BT(BT& T) {
	char a;
	scanf("%c", &a);

	if (a == '#')
		T = NULL;
	else {
		T = (BT)malloc(sizeof(BT));
		T->data = a;	//分配数据
		Create_BT(T->lchild);	//左孩子
		Create_BT(T->rchild);	//右孩子
	}
}
//输出逆序列
void Disp_Inv_Seq(BT &T)
{
	BT b[100], p;
	int top = -1, i,k;
	if(!T) return;	//无值不参与
	do {
		while (T != NULL) {
			b[++top] = T;
			T = T->lchild;	//顺序优先分配左孩子
		}
		p = NULL;	//指针先空
		k = 1;
		while (top != -1 && k) {
			T = b[top];	//取出栈顶
			if (T->rchild == p) {
				//判断是否是叶子结点
				if (T->lchild == NULL && T->rchild == NULL) {
					//输出一个逆序列
					for (i = top; i >= 0; i--)
						printf("%c ", b[i]->data);
					printf("\n");
				}
				top--;
				p = T;
			}
		    else {	//分配右孩子
				T = T->rchild;
				k = 0;
		    }
		}
	} while (top != -1);	//先分配一次,再判断是否取完
}
//主函数
int main() {
	BT T;
	Create_BT(T);
	Disp_Inv_Seq(T);
}

4.给定一个 M x N 的迷宫图、入口与出口、行走规则。求一条从指定入口到出口的路径。(注:栈、队列、递归等方法可任选一种。所求路径必须是简单路径,即路径不重复。)

1.首先设置一个二维数组,元素状态0表示通道,状态1表示障碍物。为了算法方便,一般在迷宫外围加上了一条围墙(表示为1)。

2.采取栈的顺序存储结构。对于每个方块( i , j ),都有相同的行走规则:上、下、左、右相邻方块行走。

先按从方位0到方位3的方向查找下一个可走的相邻方块。由于迷宫存在死路,走入死路需原路返回,因此还需要记下所走的方位。而退回是先进后出,因此采用栈较为方便。

3.路径不重复:

若方块(i,j)可走,则其进栈,设其方位为-1(还没试探其附近,为后面找路时不再探索(i,j),退栈时恢复为0)。再找其附近方位,若方位x附近(i1,j1)可走,则将方块(i,j)方位变为x,(i1,j1)进栈。重复操作。若方位附近不可走,则退栈。

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MaxSize 200
#define a 10
#define b 10
//定义方块结构
typedef struct {
	int i;     //方块行
	int j;     //方块列
	int di;   //下一个可走相邻方块的方位
}Block;
//定义顺序栈结构
typedef struct {
	Block data[MaxSize];
	int top;	//栈顶指针
}Zhan;
//初始化栈顶指针
void InitStack(Zhan*& s) {
	s = (Zhan*)malloc(sizeof(Zhan));
	s->top = -1;
}
//销毁栈
void DestroyStack(Zhan*& s) {
	free(s);
}
//判断栈是否为空
bool StackEmpty(Zhan* s) {
	return(s->top == -1);
}
//进栈
bool Push(Zhan*& s, Block e) {
	//如果栈满
	if (s->top == MaxSize - 1)
		return false;
	s->top++;	//栈顶指针增1
	s->data[s->top] = e;	//元素放在栈顶指针处
	return true;
}
//出栈
bool Pop(Zhan*& s, Block& e) {
	//如果栈空
	if (s->top == -1)
		return false;
	e = s->data[s->top];	//取栈顶指针元素的元素
	s->top--;	//栈顶指针减1
	return true;
}
//取栈
bool GetTop(Zhan* s, Block& e) {
	//如果栈空
	if (s->top == -1)
		return false;
	e = s->data[s->top];	//取栈顶指针元素的元素 
	return true;
}

//求解路径为(xi,yi)->(xo,yo)
bool FindRoad(int xi, int yi, int xo, int yo, char mig[a][b]) {
	Block road[MaxSize], e;
	int i, j, di, i1, j1, k;
	bool find;
	//定义和初始化栈s
	Zhan* s;
	InitStack(s);
	//设置e为入口
	e.i = xi;
	e.j = yi;
	e.di = -1;
	//进栈
	Push(s, e);
	mig[xi][yi] = -1;	//将入口置-1,避免重复探索该方块而导致死循环
	//入口已入栈,开始探索寻找出口
	while (!StackEmpty(s)) {
		//取栈顶元素e
		GetTop(s, e);
		//将栈顶方块元素赋值给i,j,di
		i = e.i;
		j = e.j;
		di = e.di;
		//判断该位置是否为出口
		if (i == xo && j == yo) {
			printf("该迷宫的一条路径为:\n");
			k = 0;	//k表示路径中的方块数
			//入口先入后出,所以要倒序输出
			while (!StackEmpty(s)) {
				Pop(s, e);			//出栈方块e
				road[k] = e;		//将e添加到road中
				k++;				//下一个方块
			}
			//k多加了1
			while (k > 0) {
				k--;
				printf("(%d,%d)->", road[k].i, road[k].j);
			}
			printf("\b\b. \n");
			DestroyStack(s);
			return true;	//输出一条迷宫路径后成功,返回true
		}
		//该位置找不到出口
		find = false;
		//找到方块(i,j)的下一个相邻方块(i1,j1)
		while (di < 4 && !find) {
			di++;	//选择下一个方位
			switch (di) {
				case 0:	i1 = i - 1; j1 = j; break;
				case 1:	i1 = i; j1 = j + 1; break;
				case 2:	i1 = i + 1; j1 = j; break;
				case 3:	i1 = i; j1 = j - 1; break;
				}
			//找到下一个可走的方块,find置为真
			if (mig[i1][j1] == 0)	find = true;
		}
		//如果找到一个相邻可走的方块(i1,j1)
		if (find) {
			//s指向栈顶元素di,改变原栈顶元素di
			s->data[s->top].di = di;
			e.i = i1;
			e.j = j1;
			e.di = -1;
			//相邻可走的方块e进栈
			Push(s, e);
			mig[i1][j1] = -1;	//将(i1,j1)迷宫值置为-1,避免重复走到该方块
		}
		//没有路可走
		else {
			Pop(s, e);				//将栈顶方块退栈
			mig[e.i][e.j] = 0;		//将退栈的方块变为其他可走的方块
		}
	}
	printf("该迷宫无路可走");	//表示没有路径可走,返回false
	DestroyStack(s);
	return false;		
}

//主函数
int main() {
	//char mig[a][b];
	int m, n;
	//输入迷宫地图
	// for(m=0;m<a;m++)
	// 	for (n = 0; n< b; n++)
	// 		scanf("%d", &mig[m][n]);
	char mig[a][b] = {
		{1,1,1,1,1,1,1,1,1,1},
		{1,0,0,0,1,1,0,0,1,1},
		{1,0,1,0,0,0,0,0,0,1},
		{1,0,0,0,1,1,1,1,1,1},
		{1,1,0,0,0,0,0,0,0,1},
		{1,1,1,1,0,1,1,0,1,1},
		{1,0,1,0,0,1,1,0,0,1},
		{1,0,0,0,1,1,0,0,1,1},
		{1,1,0,0,0,1,0,0,0,1},
		{1,1,1,1,1,1,1,1,1,1}
	};
	//输出迷宫地图
	printf("迷宫如下:\n");
	for (m = 0; m < a; m++) {
		for (n = 0; n < b; n++)
			printf("%d ", mig[m][n]);
			printf("\n");
	}
	//寻找并显示路径
	FindRoad(1,1,a-2,b-2, mig);
	return 0;
}

标签:结点,LN,top,练习,C语言,int,数据结构,data,方块
From: https://blog.csdn.net/qq_69866029/article/details/136997111

相关文章

  • c语言程序设计--实验报告二
    实验项目名称:实验报告2数据描述实验项目类型:验证性实验日期:2024年3月21日一、实验目的1、掌握C语言数据类型,熟悉如何定义一个整型、字符型和实型的变量,以及对它们赋值的方法。2、掌握不同数据类型之间赋值的规律。3、学会使用C的有关算术运算符,以及包含这些运算符的表......
  • c语言程序设计——实验报告一
    实验项目名称:实验一熟悉C语言运行环境实验项目类型:验证性实验日期:2023年3月14日一、实验目的下载安装Devc6.0程序。了解在该系统上如何进行编辑、编译、连接和运行一个C程序。通过运行简单的C程序了解C程序的特点。二、实验硬、软件环境Windows计算机、Devc6.0三、......
  • C语言 04 基本数据类型
    整数整数就是不包含小数点的数字,整数包含以下几种类型:short:占用2个字节,16个bit位。int:占用4个字节,32个bit位,能够表示-2^32到2^32之间的数字,默认使用这种类型。long:占用8个字节,64个bit位。浮点浮点类型一般用于保存小数。为啥不叫小数类型而是浮点类......
  • C语言整型提升
    C语言中整形算术运算总是至少以缺省整型类型的精度来进行的,为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。就是说表达式中各种长度可能小于int长度的整型值,都必须先转换为int或者unsignedint,然后才能送去CPU去执行运算。如......
  • Scala函数练习题
    1、定义一个高阶函数,按照指定的规则对集合里面的每个元素进行操作比如:Array(“hh”,“red”,“java”,“hadoop”)规则:对集合中每个元素进行操作,得到集合每个元素的长度objecttest{defmain(args:Array[String]):Unit={vallist=Array("hh","red","ja......
  • C语言动态内存管理(重点)
    目录1、为什么要有动态内存分配2、malloc和free2.1malloc函数2.2 free函数3、calloc和realloc3.1  calloc函数 3.2 realloc函数3.3  realloc和malloc区别3.4 realloc函数存在的问题4、常见的动态内存的错误5、动态内存经典笔试题分析6、柔性数......
  • 【数据结构】快速排序(用递归)
    大家好,我是苏貝,本篇博客带大家了解快速排序,如果你觉得我写的还不错的话,可以给我一个赞......
  • 【数据结构】希尔排序
    大家好,我是苏貝,本篇博客带大家了解希尔排序,如果你觉得我写的还不错的话,可以给我一个赞......
  • 【数据结构】归并排序(用递归)
    大家好,我是苏貝,本篇博客带大家了解归并排序,如果你觉得我写的还不错的话,可以给我一个赞......
  • C语言-扫雷游戏的简单实现
    文章目录扫雷游戏的简单实现1.初始化棋盘2.打印棋盘3.在棋盘中布置雷4.排查雷扫雷游戏的简单实现本篇博客采用了多文件的方式来实现扫雷游戏geme.h----------函数的声明及符号的定义game.c-----------函数的实现test.c-----------游戏的运行主体代码如下g......