数据结构作业

目录

实现线性表在顺序存储结构

实现线性表在顺序存储结构下的插入和删除操作。并用该存储结构实现集合A和集合B的并集和交集操作,要求最终结果存储于集合A当中。

实现单链表的插入操作

从键盘输入10个整数,用单链表存储这个数据。每次将数据插入链表的头部。并在输入完毕后,将这10个数据输出。

实现栈的顺序存储结构

实现栈的基本草错:进栈,出栈,初始化等操作。并用栈实现十进制换成八进制的转换问题。

利用栈来判断括号匹配问题

问题描述:

设某一算术表达式包含圆括号、方括号或花括号三种类型的括号,编写一个算法判断其中的括号是否匹配。

设计要求:

(1)程序对所输入的表达式能给出适当的提示信息,表达式中包含括号,括号分别为圆括号、方括号或花括号三种类型。

(2)允许使用四则混合运算(+-*/)以及包含变量的算术表达式

(3)只验证表达式中括号是否匹配(圆括号、方括号或花括号三种类型),并给出验证结果

构建二叉树

按照前序遍历的输入顺序构建一棵二叉树,要求采用二叉链表实现存储,并分别实现其递归形式的中序、后序和前序遍历。例如:下图所示的二叉树,其前序遍历顺序为:“A B C @ @ D E @ G @ @ F @ @ @”。

图的存储

用邻接表实现图的存储,并实现图的深度优先遍历。


实现线性表在顺序存储结构

实现线性表在顺序存储结构下的插入和删除操作。并用该存储结构实现集合A和集合B的并集和交集操作,要求最终结果存储于集合A当中。
#include <stdio.h>

#define MaxSize 100

typedef struct {
	int data[MaxSize];
	int length;
} Set;

void Creatset(Set *s, int a[], int n) { //创建
	int i;
	for (i = 0; i < n; i++) {
		s->data[i] = a[i];
	}
	s->length = n;
}

void Outset(Set s) { //输出
	int i;
	for (i = 0; i < s.length; i++) {
		printf("%d ", s.data[i]);
	}
	printf("\n");
}

void Insert(Set *s, int position, int element) {
	if (position < 0 || position > s->length) {
		printf("插入位置无效\n");
		return;
	}
	if (s->length >= MaxSize) {
		printf("线性表已满,无法插入\n");
		return;
	}
	for (int i = s->length; i > position; i--) {
		s->data[i] = s->data[i - 1];
	}
	s->data[position] = element;
	s->length++;
}

void Delete(Set *s, int position) {
	if (position < 0 || position >= s->length) {
		printf("删除位置无效\n");
		return;
	}
	for (int i = position; i < s->length - 1; i++) {
		s->data[i] = s->data[i + 1];
	}
	s->length--;
}

void Union(Set *A, Set B) {
	for (int i = 0; i < B.length; i++) {
		int element = B.data[i];
		int isInA = 0;
		for (int j = 0; j < A->length; j++) {
			if (A->data[j] == element) {
				isInA = 1;
				break;
			}
		}
		if (!isInA) {
			if (A->length < MaxSize) {
				A->data[A->length] = element;
				A->length++;
			} else {
				printf("集合A已满,无法添加\n");
				break;
			}
		}
	}
}

void Intersection(Set *A, Set B) {
	for (int i = 0; i < A->length; i++) {
		int element = A->data[i];
		int isInB = 0;
		for (int j = 0; j < B.length; j++) {
			if (B.data[j] == element) {
				isInB = 1;
				break;
			}
		}
		if (!isInB) {
			Delete(A, i);
			i--;
		}
	}
}

int main() {
	Set setA, setB;
	int arrayA[] = {1, 2, 3, 4, 5};
	int arrayB[] = {3, 4, 5, 6, 7};

	Creatset(&setA, arrayA, 5);
	Creatset(&setB, arrayB, 5);

	printf("集合A:");
	Outset(setA);
	printf("集合B:");
	Outset(setB);

	// 插入操作
	Insert(&setA, 2, 6);
	printf("插入后集合A:");
	Outset(setA);

	// 删除操作
	Delete(&setA, 3);
	printf("删除后集合A:");
	Outset(setA);

	// 并集操作
	Union(&setA, setB);
	printf("集合A与集合B的并集:");
	Outset(setA);

	// 重置集合A
	Creatset(&setA, arrayA, 5);

	// 交集操作
	Intersection(&setA, setB);
	printf("集合A与集合B的交集:");
	Outset(setA);

	return 0;
}

实现单链表的插入操作

从键盘输入10个整数,用单链表存储这个数据。每次将数据插入链表的头部。并在输入完毕后,将这10个数据输出。
#include <stdio.h>
#include <stdlib.h>

typedef int ElemType; // 定义链表中元素的数据类型
typedef int Status;
#define OK 1
#define ERROR 0

typedef struct LNode {
	ElemType data;         // 结点的数据域
	struct LNode *next;    // 结点的指针域
} LNode, *LinkList;

Status InitList(LinkList *L) {
	// 构造一个空链表 L
	*L = (LinkList)malloc(sizeof(LNode)); // 创建一个新结点作为头结点,并让 L 指向它
	if (!*L) {
		return ERROR; // 内存分配失败
	}
	(*L)->next = NULL; // 设置头结点的指针域为 null
	return OK;
}

Status ListInsert(LinkList L, int i, ElemType e) {
	// 在链表 L 的第 i 位置插入值为 e 的新结点
	LNode *p = L;
	int j = 0;

	while (p && j < i - 1) {
		p = p->next;
		++j; // 找到第 (i-1) 个结点,让 p 指向它
	}

	if (!p || j > i - 1)
		return ERROR; // i 超出了范围

	LNode *s = (LNode *)malloc(sizeof(LNode)); // 创建一个新结点 s
	if (!s) {
		return ERROR; // 内存分配失败
	}
	s->data = e; // 设置结点 s 的数据域为 e
	s->next = p->next; // 设置结点 s 的指针域为第 (i-1) 个结点的 next
	p->next = s; // 更新第 (i-1) 个结点的 next 指向 s

	return OK;
}

void PrintList(LinkList L) {
	// 打印链表中的元素
	LNode *p = L->next;
	while (p) {
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}

int main() {
	LinkList L;
	if (InitList(&L) != OK) {
		printf("链表初始化失败\n");
		return 1;
	}

	int input;
	printf("输入10个整数:");
	for (int i = 0; i < 10; i++) {
		scanf("%d", &input);
		if (ListInsert(L, 1, input) != OK) {
			printf("插入元素失败\n");
			return 1;
		}
	}

	printf("链表中的元素为:");
	PrintList(L);

	return 0;
}

实现栈的顺序存储结构

实现栈的基本草错:进栈,出栈,初始化等操作。并用栈实现十进制换成八进制的转换问题。
#include <stdio.h>

#define STACK_SIZE 100

struct Stack {
	int data[STACK_SIZE];
	int top;
};

void initStack(struct Stack *s) {
	s->top = -1;
}

int isEmpty(struct Stack *s) {
	return s->top == -1;
}

int isFull(struct Stack *s) {
	return s->top == STACK_SIZE - 1;
}

void push(struct Stack *s, int value) {
	if (isFull(s)) {
		printf("栈已满,无法入栈。\n");
		return;
	}
	s->data[++s->top] = value;
}

int pop(struct Stack *s) {
	if (isEmpty(s)) {
		printf("栈已空,无法出栈。\n");
		return -1;
	}
	return s->data[s->top--];
}

void decimalToOctal(int decimal) {
	struct Stack s;
	initStack(&s);

	if (decimal == 0) {
		push(&s, 0);
	}

	while (decimal > 0) {
		push(&s, decimal % 8);
		decimal /= 8;
	}

	printf("八进制表示:");
	while (!isEmpty(&s)) {
		printf("%d", pop(&s));
	}
	printf("\n");
}

int main() {
	int num;

	printf("请输入一个十进制数字:");
	scanf("%d", &num);

	decimalToOctal(num);

	return 0;
}

利用栈来判断括号匹配问题

问题描述:
设某一算术表达式包含圆括号、方括号或花括号三种类型的括号,编写一个算法判断其中的括号是否匹配。
设计要求:
(1)程序对所输入的表达式能给出适当的提示信息,表达式中包含括号,括号分别为圆括号、方括号或花括号三种类型。
(2)允许使用四则混合运算(+-*/)以及包含变量的算术表达式
(3)只验证表达式中括号是否匹配(圆括号、方括号或花括号三种类型),并给出验证结果
#include <stdio.h>
#include <stdlib.h>

#define MAX_STACK_SIZE 100

struct Stack {
	char items[MAX_STACK_SIZE];
	int top;
};

void init(struct Stack *stack) {
	stack->top = -1;
}

int isEmpty(struct Stack *stack) {
	return (stack->top == -1);
}

int isFull(struct Stack *stack) {
	return (stack->top == MAX_STACK_SIZE - 1);
}

void push(struct Stack *stack, char item) {
	if (!isFull(stack)) {
		stack->items[++(stack->top)] = item;
	}
}

char pop(struct Stack *stack) {
	if (!isEmpty(stack)) {
		return stack->items[(stack->top)--];
	}
	return '\0'; // 栈为空时返回空字符
}

int Match(char *s) {
	struct Stack stack;
	init(&stack);

	for (int i = 0; s[i] != '\0'; i++) {
		char current = s[i];

		if (current == '(' || current == '[' || current == '{') {
			push(&stack, current);
		} else if (current == ')' || current == ']' || current == '}') {
			if (isEmpty(&stack)) {
				return 0; // 括号不匹配
			} else {
				char top = pop(&stack);
				if ((current == ')' && top != '(') || (current == ']' && top != '[') || (current == '}' && top != '{')) {
					return 0; // 括号不匹配
				}
			}
		}
	}

	return isEmpty(&stack); // 如果栈为空,说明括号匹配
}

int main() {
	char s[100];

	printf("请输入包含括号的表达式: ");
	scanf("%s", s);

	if (Match(s)) {
		printf("括号匹配\n");
	} else {
		printf("括号不匹配\n");
	}

	return 0;
}

构建二叉树

按照前序遍历的输入顺序构建一棵二叉树,要求采用二叉链表实现存储,并分别实现其递归形式的中序、后序和前序遍历。例如:下图所示的二叉树,其前序遍历顺序为:“A B C @ @ D E @ G @ @ F @ @ @”。

根节点为A A的左儿子为B B的左儿子为C B的右儿子为D D的左儿子为E D的右儿子为F E的右儿子为G

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

struct TreeNode {
	char value;
	struct TreeNode *left;
	struct TreeNode *right;
};

struct TreeNode *buildBinaryTree() {
	char value;
	printf("请输入节点的值 (或输入 '@' 表示空节点): ");
	scanf(" %c", &value);

	if (value == '@') {
		return NULL;
	}

	struct TreeNode *node = (struct TreeNode *)malloc(sizeof(struct TreeNode));
	node->value = value;

	printf("为节点 %c 添加左儿子:\n", value);
	node->left = buildBinaryTree();

	printf("为节点 %c 添加右儿子:\n", value);
	node->right = buildBinaryTree();

	return node;
}

void inorderTraversal(struct TreeNode *node) {
	if (node != NULL) {
		inorderTraversal(node->left);
		printf("%c ", node->value);
		inorderTraversal(node->right);
	} else {
		printf("@ ");
	}
}

void postorderTraversal(struct TreeNode *node) {
	if (node != NULL) {
		postorderTraversal(node->left);
		postorderTraversal(node->right);
		printf("%c ", node->value);
	} else {
		printf("@ ");
	}
}

void preorderTraversal(struct TreeNode *node) {
	if (node != NULL) {
		printf("%c ", node->value);
		preorderTraversal(node->left);
		preorderTraversal(node->right);
	} else {
		printf("@ ");
	}
}

int main() {
	struct TreeNode *root = NULL;
	printf("请输入根节点的值:\n");
	root = buildBinaryTree();

	printf("中序遍历:\n");
	inorderTraversal(root);
	printf("\n");

	printf("后序遍历:\n");
	postorderTraversal(root);
	printf("\n");

	printf("前序遍历:\n");
	preorderTraversal(root);
	printf("\n");

	return 0;
}

图的存储

用邻接表实现图的存储,并实现图的深度优先遍历。

13 22
0 1 2 3 4 5 6 7 8 9 10 11 12
0 1
0 5 
2 0 
2 3 
3 2 
3 5 
4 2 
4 3 
5 4 
6 0 
6 4 
6 9 
7 6 
7 8 
8 7 
8 9
9 10 
9 11 
10 12 
11 4
11 12 
12 9

#include <stdio.h>
#include <stdlib.h>
 
#define MAX_VERTICES 100
 
typedef struct EdgeNode {
	int dest;
	struct EdgeNode *link;
} EdgeNode;
 
typedef struct {
	int data;
	EdgeNode *firstAdj;
} VexList;
 
int n, e;
int vis[MAX_VERTICES];
 
void createGraph(VexList v[]) {
	scanf("%d %d", &n, &e);
	for (int i = 0; i < n; i++) {
		scanf("%d", &v[i].data);
		v[i].firstAdj = NULL;
	}
 
	for (int i = 0; i < e; i++) {
		int head, tail;
		scanf("%d %d", &tail, &head);
		EdgeNode *p = (EdgeNode *)malloc(sizeof(EdgeNode));
 
		p->dest = head;
		p->link = v[tail].firstAdj;
		v[tail].firstAdj = p;
	}
}
 
int getFirstNeighbor(VexList v, EdgeNode **p) {
	if (v.firstAdj == NULL)
		return -1;
 
	else {
		*p = v.firstAdj;
		return (*p)->dest;
	}
}
 
int getNextNeighbor(EdgeNode **p) {
	if (*p == NULL)
		return -1;
	else {
		*p = (*p)->link;
		return (*p == NULL) ? -1 : (*p)->dest;
	}
}
 
void DFS(VexList v[], int x) {
	EdgeNode *p = NULL;
	vis[x] = 1;
	printf("%d ", v[x].data);
	int w = getFirstNeighbor(v[x], &p);
	while (w != -1) {
		if (!vis[w])
			DFS(v, w);
		w = getNextNeighbor(&p);
	}
}
 
 
int main() {
	VexList v[MAX_VERTICES];
	createGraph(v);
 
	printf("深搜遍历结果:");
	for (int i = 0; i < n; i++)
		if (!vis[i])
			DFS(v, i);
	printf("\n");
 
	return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

地图室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值