数据结构c语言版课程设计_数据结构与算法c语言版电子书

数据结构c语言版课程设计_数据结构与算法c语言版电子书设计一个应用程序(C/C++),利用多级菜单实现单链表、栈、队列、二叉树及图五种结构的基本操作及应用


仅供自己学习使用


一、设计任务

  设计一个应用程序(C/C++),利用多级菜单实现单链表、栈、队列、二叉树及图五种结构的基本操作及应用。具体内容包括:

  1. 单链表的基本操作及应用
    ①创建
    ②插入
    ③删除
    ④查找
    ⑤应用
    注:利用基本操作(可扩展)实现单链表的应用,如一元多项式运算、通讯录设计等。
  2. 栈的基本操作及应用
    ①进栈
    ②出栈
    ③取栈顶元素
    ④应用
    注:利用基本操作(可扩展)实现栈的应用,如表达式求值、深度优先遍历等。
  3. 队列的基本操作及应用
    ①入列
    ②出列
    ③取队头元素
    ④取队尾元素
    ⑤应用
    注:利用基本操作(可扩展)实现队列的应用,如酒店客房分配、广度优先遍历等。
  4. 二叉树的基本操作及应用
    ①创建
    ②遍历(先序、中序、后序)
    ③求结点个数
    ④求树的深度
    ⑤查找双亲
    ⑥查找兄弟(左/右)
    ⑦查找孩子(左/右)
    ⑧应用
    注:利用基本操作(可扩展)实现二叉树的应用,如二叉排序树、Huffman编码等。
  5. 图的基本操作及应用
    ①创建(邻接矩阵/邻接表)
    ②遍历(深度/广度)
    ③定位
    ④找第一个邻接点
    ⑤找下一个邻接点
    ⑥插入(点/边)
    ⑦删除(点/边)
    ⑧应用
    注:利用图的基本操作(可扩展)实现图的应用,如拓扑排序、关键路径等。

二、运行效果图运行效果图

三、部分源代码

1. bitree.h

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

//二叉树结构体
typedef struct BiTNode { 
   
	char data;
	struct BiTNode* lchild, * rchild;
} BiTNode, * BiTree;

//初始化
Status InitBiTree(BiTree& T) { 
   
	T = (BiTree)malloc(sizeof(BiTNode));
	if (!T) { 
   
		printf("内存分配失败。\a\n\n");
	}
	T->lchild = T->rchild = NULL;
	return OK;
}

//先序创建
void CreateBiTree(BiTree& T) { 
   
	char ch;
	printf("请输入结点数据(先序):");
	scanf_s("%c", &ch);
	getchar();
	if (ch == '*')
		T = NULL;
	else { 
   
		T = new BiTNode;
		T->data = ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
}
//先序遍历
void PreOrderTraverse1(BiTree T) { 
   

	if (T) { 
   
		printf("%c", T->data);
		PreOrderTraverse1(T->lchild);
		PreOrderTraverse1(T->rchild);
	}
}
//中序遍历
void InOrderTraverse2(BiTree T) { 
   

	if (T) { 
   
		InOrderTraverse2(T->lchild);
		printf("%c", T->data);
		InOrderTraverse2(T->rchild);
	}
}
//后序遍历
void PostOrderTraverse3(BiTree T) { 
   

	if (T) { 
   
		PostOrderTraverse3(T->lchild);
		PostOrderTraverse3(T->rchild);
		printf("%c", T->data);
	}
}
//二叉树深度
int Depth(BiTree T) { 
   
	int n, m;
	if (T == NULL)
		return 0;
	else { 
   
		m = Depth(T->lchild);
		n = Depth(T->rchild);
		if (m > n)
			return(m + 1);
		else
			return(n + 1);
	}
}
//叶子结点个数
int LeafCount(BiTree T) { 
   
	if (T == NULL)
	{ 
   
		return 0;
	}
	if ((T->lchild == NULL) && (T->rchild == NULL))
	{ 
   
		return 1;
	}
	return LeafCount(T->lchild) + LeafCount(T->rchild);
}
//查找双亲
Status Parent(BiTree T, char e)// 初始条件:二叉树T存在,e是T中某个结点
// 操作结果:若e是T的非根结点,则返回它的双亲;否则返回“空”
{ 
   
	Status m;
	if (T == NULL) // 空树
		return 0;
	if ((T->lchild && T->lchild->data == e) || (T->rchild && T->rchild->data == e)) { 
   
		printf("结点的双亲数据是:%c\n\n",T->data);
		return OK;
	}
	m = Parent(T->lchild, e);
	if (m == 0)   m = Parent(T->rchild, e);
	return m;
}
//查找兄弟
Status Brother(BiTree T, char e) { 
   
	Status m;
	if (T == NULL) // 空树
		return 0;
	if (T->lchild && T->lchild->data == e) { 
   
		printf("结点存在右兄弟,且右兄弟数据是:%c\n\n", T->rchild->data);
		return OK;
	}
	if (T->rchild && T->rchild->data == e) { 
   
		printf("结点存在左兄弟,且左兄弟数据是:%c\n\n", T->lchild->data);
		return OK;
	}
	m = Brother(T->lchild, e);
	if (m == 0)  m = Brother(T->rchild, e);
	return m;
}

// 查找孩子
Status Child(BiTree T, char e) { 
   
	Status m;
	if (T == NULL) { 
   
		return 0;
	}
	if (T->data == e) { 
   
		if (T->lchild && !T->rchild) { 
   
			printf("存在左孩子,且左孩子数据是:%c\n\n",T->lchild->data);
			return OK;
		}
		if (T->rchild && !T->lchild) { 
   
			printf("存在左孩子,且左孩子数据是:%c\n\n", T->rchild->data);
			return OK;
		}
		if (T->rchild && T->lchild) { 
   
			printf("左孩子数据是:%c,右孩子数据是:%c\n\n",T->lchild->data,T->rchild->data);
			return OK;
		}
	}
	m = Child(T->lchild, e);
	if (m == 0)  m = Child(T->rchild, e);
	return m;
}

// 二叉树的应用


///*********** 测试 *************/
//int main(void) { 
   
// BiTree root;
// CreateBiTree(root);
// printf("\n");
// // //printf("先序遍历结果是:");
// // //PreOrderTraverse1(root);
// // //printf("\n");
// // //printf("中序遍历结果是:");
// // //InOrderTraverse2(root);
// // //printf("\n");
// // //printf("后序遍历结果是:");
// // //PostOrderTraverse3(root);
// // //printf("\n");
// // printf("您所创建的二叉树深度是:%d\n\n", Depth(root));
// // printf("您所创建的二叉树的叶子结点个数是:%d\n\n", LeafCount(root));
// // char data;
// // printf("请您输入要查找双亲的结点信息:");
// // scanf_s("%c", &data);
// // if (!Parent(root, data)) { 
   
// // printf("不存在该结点或该结点是根结点。\a\n\n");
// // }
// char data;
// printf("请您输入要查找兄弟的结点信息:");
// scanf_s("%c", &data);
// if (!Child(root, data)) { 
   
// printf("不存在该结点或该结点是叶子结点。\a\n\n");
// }
// return 0;
//}
}

2. LinkList.h

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


typedef struct LNode { 
   
	int data;
	struct LNode* next;
}LNode, *Linklist;

Status ListInit(Linklist& L) { 
    // 初始化
	L = (LNode*)malloc(sizeof(LNode));
	if (!L) { 
   
		printf("内存分配失败!\a\n");
		exit(ERROR);
	}
	L->next = NULL;
	L->data = 0; //头节点的数据存放结点个数
	printf("单链表初始化成功!\n\n");
	return OK;
}

Status ListCreate(Linklist& L) { 
     // 创建(尾插法)
	int i; // i是循环变量
	int n;//n用于记录元素个数
	printf("请输入元素个数:");
	scanf_s("%d", &n);
	for (i = 0; i < n; i++) { 
   
		LNode* newNode = (LNode*)malloc(sizeof(LNode));
		if (!newNode) { 
   
			printf("内存分配失败!\a\n");
			exit(ERROR);
		}
		printf("\t请输入第%d个元素的数据:", n - i);
		scanf_s("%d", &newNode->data);
		newNode->next = L->next;
		L->next = newNode;
		L->data++;
	}
	printf("单链表创建成功!\n\n");
	return OK;
}

Status ListInsert(Linklist L) { 
     // 插入
	LNode* sign = L;
	int j = 0;
	int location;
	printf("请输入要插入的位置:");
	scanf_s("%d", &location);
	while (sign && j < location - 1) { 
   
		sign = sign->next;
		++j;
	}
	if (!sign || j > location - 1) { 
   
		printf("位置不合法!\a\n");
		exit(ERROR);
	}
	LNode* newNode = (LNode*)malloc(sizeof(LNode));
	if (!newNode) { 
   
		printf("内存分配失败!\a\n");
		exit(ERROR);
	}
	printf("请输入要插入的数据:");
	scanf_s("%d", &newNode->data);
	newNode->next = sign->next;
	sign->next = newNode;
	L->data++;
	printf("插入成功!\n\n");
	return OK;
}

int ListDelete(Linklist L) { 
     //删除
	int location;
	printf("请输入要删除元素所在的位置:");
	scanf_s("%d", &location);
	int j = 0;
	LNode* sign = L;
	while (sign->next && j < location - 1) { 
   
		sign = sign->next;
		++j;
	}
	if (!sign || j > location - 1) { 
   
		printf("位置不合法!\a\n");
		exit(ERROR);
	}
	LNode* temp = sign->next;
	sign->next = temp->next;
	int data = temp->data;
	free(temp);
	printf("删除成功!\n\n");
	return data;
}

Status ListShow(Linklist& L) { 
     //打印
	LNode* sign = L->next;
	int i = 1;
	printf("现在开始打印单链表中的数据:\n");
	while (sign) { 
   
		printf("\t第%d个数据是:%d\n", i++, sign->data);
		sign = sign->next;
	}
	printf("数据打印完毕!\n\n");
	return OK;
}

Status ListLocate(Linklist& L) { 
    //查找
	int data;
	int location = 1; //记录元素位置
	printf("请输入您要查找的元素:");
	scanf_s("%d", &data);
	LNode* sign = L->next;
	while (sign && sign->data != data) { 
   
		sign = sign->next;
		location++;
	}
	if (!sign) { 
   
		printf("当前链表中不存在您要查找的元素。\n\n");
		return FALSE;
	}
	else { 
   
		printf("元素所在位置是第%d个。\n\n", location);
		return OK;
	}
}

// 单链表的应用,多项式相加减
typedef struct pnode
{ 
   
	int coef;   //系数
	int exp;   // 指数
	struct pnode* next;  // 后继指针
}PolyNode;

PolyNode* aHead, * bHead;

void DispPoly(PolyNode* head)
{ 
   
	PolyNode* p;
	p = head;
	while (p != NULL)
	{ 
   
		if (p->coef > 0 && p != head)
		{ 
   
			printf("+");
		}
		if (p->exp == 0)
		{ 
   
			printf("%d", p->coef);
		}
		else if (p->exp == 1)
		{ 
   
			printf("%dx", p->coef);
		}
		else
		{ 
   
			printf("%dx^%d", p->coef, p->exp);
		}
		p = p->next;
	}
	printf("\n");
}



void createList(PolyNode*& head)
{ 
   
	int m; // m代表多项式的系数
	while (1)
	{ 
   
		printf("\n\t\t请输入多项式的项数:");
		scanf_s("%d", &m);
		if (m != 0)
		{ 
   
			break;
		}
		else
		{ 
   
			printf("\n\t\t不允许输入 0 项!请重新输入!\n");
		}
	}

	PolyNode* p = NULL, * s = NULL;
	for (int i = 0; i < m; i++)
	{ 
   

		p = (PolyNode*)malloc(sizeof(PolyNode));
		printf("\n\t\t第%2d项 系数:", i + 1);
		scanf_s("%d", &p->coef);
		printf("\t\t\t指数:");
		scanf_s("%d", &p->exp);
		if (head == NULL)
		{ 
   
			head = p;
		}
		else
		{ 
   
			s->next = p;
		}
		s = p;
	}

	s->next = NULL;
}

void Add(PolyNode*& ahead, PolyNode*& bhead)
{ 
   
	PolyNode* p = NULL, * q = NULL, * s = NULL;
	q = aHead;
	while (q != NULL)
	{ 
   
		p = q;
		q = q->next;
	}
	p->next = bHead;
	printf("\n\n\t\t连接:");
	DispPoly(aHead);

	q = aHead;
	while (q != NULL)
	{ 
   
		p = q;
		s = q;
		p = p->next;
		while (p != NULL)
		{ 
   
			if (p->exp == q->exp)
			{ 
   
				q->coef = q->coef + p->coef;
				s->next = p->next;
				free(p);
				p = s;
			}
			s = p;
			p = p->next;
		}
		q = q->next;
	}
	printf("\n\t\t相加得多项式:");
	DispPoly(aHead);
}

void Sub(PolyNode*& ahead, PolyNode*& bhead)
{ 
   
	PolyNode* p = NULL, * q = NULL, * s = NULL;
	q = aHead;
	while (q != NULL)
	{ 
   
		p = q;
		if (q->coef > 0) q->coef = -(q->coef);
		q = q->next;
	}
	p->next = bHead;
	printf("\n\n\t\t连接:");
	DispPoly(aHead);

	q = aHead;
	while (q != NULL)
	{ 
   
		p = q;
		s = q;
		p = p->next;
		while (p != NULL)
		{ 
   
			if (p->exp == q->exp)
			{ 
   
				q->coef = q->coef + p->coef;
				s->next = p->next;
				free(p);
				p = s;
			}
			s = p;  
			p = p->next;
		}
		q = q->next;
	}
	printf("\n\t\t相减得多项式:");
	DispPoly(aHead);
}

/*********** 测试 *************/
//int main(void) { 
   
// Linklist L = NULL;
// ListInit(L); //初始化单链表
// ListCreate(L); //创建单链表
// // ListShow(L); //打印单链表
// //ListInsert(L); //插入到单链表
// //printf("此时单链表中一共有%d个元素.\n", L->data);
// //ListShow(L); //打印单链表
// //ListDelete(L);
// //ListShow(L); //打印单链表
// ListLocate(L);
//}

3. map.h

#include <iostream>
using namespace std;
#define MAX 100 //最大顶点数
bool visited[MAX];  //标志数组,用于标记顶点是否被访问过

//边的存储结构
typedef struct BNode
{ 
   
	int pointPosite;             //该边所指向顶点的位置
	struct BNode* nextB;         //指向下一条边的指针
	int info;            		 //和边相关的信息
}BNode;

//顶点的存储结构
typedef struct DNode
{ 
   
	string data;                //存放顶点信息
	BNode* firstB;              //指针指向第一条依附该顶点的边
}DNode, AdjList[MAX];			//AdjList表领接表类型

//邻接表的存储结构
typedef struct
{ 
   
	AdjList vertices;           //顶点向量
	int DNum, BNum;             //图的当前顶点数和边数
}TGraph;

//顺序队列的存储表示
typedef struct
{ 
   
	string* base;  	//存储空间的基地址
	int front;		//头指针
	int rear;		//尾指针
}SqQueue;

//队列的初始化
void InitQueue(SqQueue& Q)
{ 
   //构造一个空队列
	Q.base = new string[MAX];
	if (!Q.base)
	{ 
   
		cout << "内存分配失败" << endl;
	}
	Q.front = Q.rear = 0;
}

// 入队
void EnQueue(SqQueue& Q, string e)
{ 
   
	if ((Q.rear + 1) % MAX == Q.front)
	{ 
   
		cout << "队列已满" << endl;
	}
	Q.base[Q.rear] = e;
	Q.rear = (Q.rear + 1) % MAX;
}

// 出队
string DeQueue(SqQueue& Q, string& e)
{ 
   
	if (Q.front == Q.rear)
	{ 
   
		cout << "队列为空" << endl;
	}
	e = Q.base[Q.front];
	Q.front = (Q.front + 1) % MAX;
	return e;
}

// 判断队列是否尾空
bool Empty(SqQueue Q)
{ 
   
	if (Q.front == Q.rear)
	{ 
   
		return true;
	}
	return false;
}

// 找所给顶点在图中的序号
int LocateVex(TGraph G, string v)
{ 
   
	for (int i = 0; i < G.DNum; ++i)
	{ 
   
		if (v == G.vertices[i].data)
		{ 
   
			return i;
		}
	}
	return -1;
}

// 邻接表创建无向图
void CreateUDG(TGraph& G)       //无向图UDG
{ 
   
	string v1, v2;
	cout << "请输入所要创建图的总顶点数和总边数:";
	cin >> G.DNum >> G.BNum;         //输入总顶点数和总边数
	for (int i = 0; i < G.DNum; ++i) //输入各点,构造表头结点表
	{ 
   
		cout << "请输入第" << i + 1 << "个顶点的值:";
		cin >> G.vertices[i].data;    //输入顶点值
		G.vertices[i].firstB = NULL;//初始化表头结点指针域为空
	}
	for (int k = 0; k < G.BNum; ++k) //输入各边,构造领接表
	{ 
   
		BNode* p1, * p2;
		cout << "请输入第" << k + 1 << "条边的信息:";
		cin >> v1 >> v2;                //输入一条边依附的两个顶点
		int m = LocateVex(G, v1); int n = LocateVex(G, v2); //得到v1 v2在G.vertices中的序号
		p1 = new BNode;         //生成一个新的边结点*p1
		p1->pointPosite = n;    //邻接点序号为n
		p1->nextB = G.vertices[m].firstB;   //头插法
		G.vertices[m].firstB = p1;
		p2 = new BNode;
		p2->pointPosite = m;
		p2->nextB = G.vertices[n].firstB;
		G.vertices[n].firstB = p2;
	}
	cout << "无向图创建成功。\n\n";
}

// 打印图的邻接表
void UDGprint(TGraph G)
{ 
   
	BNode* p;
	for (int i = 0; i < G.DNum; ++i)
	{ 
   
		cout << G.vertices[i].data;
		p = G.vertices[i].firstB;
		while (p)
		{ 
   
			cout << ": ";
			cout << p->pointPosite;
			p = p->nextB;
		}
		cout << endl;
	}
}

// 深度优先遍历
void deepTravel(TGraph G, string v)
{ 
   
	int b, w;
	BNode* p;
	cout << v << " ";
	b = LocateVex(G, v);
	visited[b] = true;  //访问第b个顶点,标志为true
	p = G.vertices[b].firstB;    //p指向v的边链表的第一个边结点
	while (p != NULL)            //如果p不为空
	{ 
   
		w = p->pointPosite;     //w为v的第一个边结点
		if (!visited[w])         //若w未被访问 则继续递归
		{ 
   
			string a;
			for (int i = 0; i < G.DNum; ++i)
			{ 
   
				if (w == i)
				{ 
   
					a = G.vertices[i].data;
				}
			}
			deepTravel(G, a);
		}
		p = p->nextB;       //否则p指向下一个v的边结点
	}
}

// 广度优先遍历
void breadthTravel(TGraph G, string v)
{ 
   
	BNode* p;
	int l;
	string e;
	int b = LocateVex(G, v);
	SqQueue Q;
	InitQueue(Q);
	for (int i = 0; i < G.DNum; i++)
		visited[i] = false;
	if (!visited[b])
	{ 
   
		visited[b] = true;
		cout << v << " ";
		EnQueue(Q, v);
		while (!Empty(Q))
		{ 
   
			string s = DeQueue(Q, e);
			int u = LocateVex(G, s);
			p = G.vertices[u].firstB;
			while (p)
			{ 
   
				l = p->pointPosite;
				if (!visited[l])
				{ 
   
					visited[l] = true;
					cout << G.vertices[l].data << " ";
					EnQueue(Q, G.vertices[l].data);
				}
				p = p->nextB;
			}
		}
	}
}

// 查找第一个邻接点
int FirstAdjVex(TGraph G, string v)
{ 
   
	BNode* p;
	int v1;
	v1 = LocateVex(G, v);//v1为顶点v在图G中的序号
	p = G.vertices[v1].firstB;
	if (p)
	{ 
   
		return p->pointPosite;
	}
	else
	{ 
   
		return -1;
	}
}

// 查找下一个邻接点
int NextAdjVex(TGraph G, string v, string w)
{ 
   
	BNode* p;
	int v1, v2;
	v1 = LocateVex(G, v);//v1为顶点v在图G中的序号
	v2 = LocateVex(G, w);//v2为顶点v在图G中的序号
	p = G.vertices[v1].firstB;
	for (; p->nextB && p->pointPosite != v2; p = p->nextB);
	if (p->nextB && p->pointPosite == v2)
	{ 
   
		return p->nextB->pointPosite;
	}
	else
	{ 
   
		return -1;
	}
}

// 插入结点
void InsertNode(TGraph& G, string data)
{ 
   
	G.DNum++;
	G.vertices[G.DNum - 1].data = data;
	G.vertices[G.DNum - 1].firstB = NULL;
	printf("插入成功。\n\n");
}

// 删除结点
void DeleteNode(TGraph& G, string data)
{ 
   
	int c = LocateVex(G, data);
	BNode* p, * q;
	for (int i = 0; i < G.DNum; ++i)
	{ 
   
		p = G.vertices[i].firstB;
		q = p;
		if (G.vertices[i].firstB->pointPosite)
			if (c > G.vertices[i].firstB->pointPosite)
			{ 
   
				q = p;
				p = p->nextB;
			}
			else if (G.vertices[i].firstB->pointPosite == c)
			{ 
   
				G.vertices[i].firstB = p->nextB;
				q = G.vertices[i].firstB;
				p = p->nextB;
				while (p)
				{ 
   
					if (c > p->pointPosite)
					{ 
   
						q = p;
						p = p->nextB;
					}
					else
					{ 
   
						p->pointPosite -= 1;
						q = p;
						p = p->nextB;
					}
				}
				continue;
			}
			else
			{ 
   
				G.vertices[i].firstB->pointPosite -= 1;
				q = p;
				p = p->nextB;
			}
		while (p)
		{ 
   
			if (c > p->pointPosite)
			{ 
   
				p = p->nextB;
			}
			else if (c == p->pointPosite)
			{ 
   
				q->nextB = p->nextB;
				p = p->nextB;

				while (p)
				{ 
   
					if (c > p->pointPosite)
					{ 
   
						p = p->nextB;
					}
					else
					{ 
   
						p->pointPosite -= 1;
						p = p->nextB;
					}
				}
				continue;
			}
			else
			{ 
   
				p->pointPosite -= 1;
				q = p;
				p = p->nextB;
			}
		}
	}
	for (int j = 0; j < G.DNum; j++)
	{ 
   
		if (G.vertices[j].data == data)
		{ 
   
			for (; j < G.DNum; j++)
			{ 
   
				G.vertices[j] = G.vertices[j + 1];
			}
			G.DNum -= 1;
			break;
		}
	}
}

/**********应用**********/
// 判断图的联通性
bool Judge(TGraph G)
{ 
   
	for (int v = 0; v < G.DNum; v++)
	{ 
   
		visited[v] = false;
	}
	deepTravel(G, G.vertices[0].data);                      //从任意一点遍历,这里从下标为0的点开始
	for (int v = 0; v < G.DNum; v++)
	{ 
   
		if (!visited[v])
		{ 
   
			return false;
		}
	}
	return true;
}


/**************测试***************/
//int main()
//{ 
   
// string ch;
// TGraph G;
// CreateUDG(G);
// cout << "建立的邻接表如下: " << endl;
// UDGprint(G);
// cout << "请输入遍历开始的结点:";
// cin >> ch;
// cout << "深度遍历序列为: ";
// deepTravel(G, ch);
// cout << "\n广度遍历序列为: ";
// breadthTravel(G, ch);
// return 0;
//}

完整下载链接

数据结构课程设计

今天的文章数据结构c语言版课程设计_数据结构与算法c语言版电子书分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/83254.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注