SDU 数据结构实验作业

本文涵盖了一系列数据结构与算法的实验,包括递归全排列、排序算法、线性表操作、堆栈应用、二叉树操作、堆与搜索树以及图的操作。通过这些实验,深入理解了各种数据结构的特性和算法的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

+## 实验一 递归练习

1、 输入2-10个大于0的正整数,如果输入0作为结束。
2、 输出这几个整数的全排列,每个数之间用半角“,”隔开,中间不要有空格,每个排列单独一行。
3、 程序一定要有Input、Output、End提示信息,但是不要有格式没有出现的其他提示,以下各实验相同。
4、 程序最后增加system(pause),显示Press any key to continue并暂停。

#include <iostream>
using namespace std;

void Permutation(int data[],int start,int end);
void Swap(int& a,int& b);

int main()
{
	cout<<"Input"<<endl;
	int data[10],i=0;
	while(true){
		cin>>data[i];
		if(data[i]==0){
			break;
		}
		i++;
		
	}
	cout<<"Output"<<endl;
	
	Permutation(data,0,i);
//	cout<<"Press any key to continue"<<endl;
	cout<<"End"<<endl;
	system("pause");
	return 0;
 } 
void Permutation(int data[],int start,int end){
 	int i;
 	if(start==end){
 		for(int j=0;j<end;j++){
 			if(j==end-1){
 				cout<<data[j]<<endl;
 				break;
			 }else{
			 	cout<<data[j]<<",";
			 }
		 }
	 }
	 for(i=start;i<end;i++){
	 	Swap(data[start],data[i]);
	 	Permutation(data,start+1,end);
	 	Swap(data[start],data[i]);
	 }
 	
}
void Swap(int& a,int& b){
	int temp;
	temp=a;a=b;b=temp;
}

运行结果:
在这里插入图片描述

实验二 排序算法

1、 输入2-10个不为零的正整数,遇到0代表输入结束,0不参与排序。
2、 数字选择排序方法,1-冒泡排序、2-插入排序、3-基数排序
3、 基数排序能够实现小于10的正整数的排序。
4、 使用所选排序方法的排序,结果输出所用方法以及结果,每个数之间用“,”隔开,中间不要有空格。
5、 输入输出请严格按下面要求的格式实现

// ConsoleApplication2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
using namespace std;

void Bubble(int data[], int i);
void Print(int data[], int i);
void InsertSort(int data[], int i);
void Insert(int data[], int temp, int i);
void RadixSort(int data[], int i);

int main()
{
	cout << "Input" << endl;
	int data[11], i = 0;
	while (true) {
		cin >> data[i];
		if (data[i] == 0) {
			break;
		}
		i++;

	}
	cout << "1-冒泡排序,2-插入排序,3-基数排序" << endl;
	int j;
	cin >> j;
	switch (j) {
	case 1:
		cout << "Output" << endl << "冒泡排序" << endl;
		Bubble(data, i);
		break;
	case 2:
		cout << "Output\n插入排序\n";
		InsertSort(data, i);
		break;
	case 3:
		cout << "Output\n基数排序\n";
		RadixSort(data, i);
		break;

	}
	cout << "End" << endl;
	system("pause");
	return 0;
}
void Bubble(int data[], int i) {
	int temp = 0;
	for (int j = 0; j < i; j++) {
		for (int k = j; k < i; k++) {
			if (data[j] > data[k]) {
				temp = data[j]; data[j] = data[k]; data[k] = temp;
			}
		}
	}
	Print(data, i);
}
void InsertSort(int data[], int i) {
	int temp;
	for (int j = 1; j < i; j++) {
		temp = data[j];
		Insert(data, temp, j);
	}
	Print(data, i);
}
void RadixSort(int data[], int i) {
	int **point = new int*[10];
	int a = 0;
	while (a < 10) {
		point[a] = new int[10];
		a++;
	}
	int b = 0, d;
	for (int c = 1; c < 10; c++) {
		d = 0; b = 0;
		point[c][d] = 0;
		while (b < i) {
			if (data[b] == c) {
				point[c][d] = c;
				d++;
				point[c][d] = 0;

			}
			b++;
		}

	}
	b = 0;
	for (int c = 1; c < 10; c++) {
		d = 0;
		while (point[c][d] != 0) {
			data[b] = point[c][d];
			b++; d++;
		}
	}
	Print(data, i);

}
void Insert(int data[], int temp, int i) {
	int j;
	for (j = i - 1; j >= 0 && temp < data[j]; j--) {
		data[j + 1] = data[j];
	}
	data[j + 1] = temp;
}
void Print(int data[], int i) {
	for (int j = 0; j < i; j++) {
		if (j == i - 1) {
			cout << data[j] << endl;
			break;
		}
		else {
			cout << data[j] << ",";
		}
	}
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

运行结果:
在这里插入图片描述

实验三 线性表操作

1、 1、 输入n个不为零的整数作为节点元素值,遇到0代表输入结束(不创建元素值为0的节点),创建有序链表。输出整个链表。
2、 输入一个整数,将该数插入到有序表相应位置。输出整个链表。
3、 输入一个整数,在链表中进行搜索,输出其在链表中的位置。如果不存在输出0。
4、 再一次输入一个整数,在链表中进行搜索,输出其在链表中的位置。如果不存在输出0。
5、 再一次输入n个不为零的整数作为节点元素值,遇到0代表输入结束(不创建元素值为0的节点),创建有序链表。输出整个链表。
6、 使用链表遍历器实现上面两个有序链表的合并,输出合并后的链表。
7、 提示:注意单节点链表的测试

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
using namespace std;

class Chain;
class ChainNode {
	friend Chain;
private:
	int data;
	ChainNode *link;
};
class Chain {
public:
	Chain() {
		first = new ChainNode;
		first->link = 0; first->data = 0;
	}
	Chain & Merge(Chain &x);
	Chain & Append(int a);
	void Output(ostream& out);
	Chain & Insert(int i, int x);
	int Find(int x);
	Chain & Reverse();
private:
	ChainNode *first;
};
Chain & Chain::Reverse() {
	ChainNode *a;
	ChainNode *b;
	ChainNode *current;
	if (first->link->link) {
		current = first->link->link->link;
		a = first->link;
		b = a->link;
		if (current) {
			a->link = 0;
			while (current) {
				b->link = a;
				a = b; b = current; current = current->link;
			}
			b->link = a; first->link = b;
		}
		else {
			a->link = 0; b->link = a; first->link = b;
		}

	}
	else {
		return *this;
	}
	return *this;

}
//合并
Chain & Chain::Merge(Chain &x) {
	ChainNode *current;
	ChainNode *current2;
	Chain *temp1=new Chain;
	ChainNode *temp = temp1->first;
	current2 = x.first->link;
	for (current = first->link; current&&current2; ) {
		if (current->data >= current2->data) {
			temp->link = current2;
			
			current2 = current2->link;
			temp = temp->link;
			if (current2) {
				
			}
			else {
				temp->link = current;
			}
		}
		else {
			temp->link = current;
			temp = temp->link;
			current = current->link;
			if (current) {

			}
			else {
				temp->link = current2;
			}
		}
		



	}
	
	return *temp1;
}
Chain & Chain::Append(int a) {
	ChainNode *y;
	y = new ChainNode;
	y->data = a; y->link = 0;
	ChainNode *current = first;
	if (first) {
		while (current->link&&a>=current->link->data) {
			current = current->link;

		}
		if (current->link) {
			y->link = current->link;
			
			current->link = y;

		}
		else {
			current->link = y;
		}
		
	}
	else {
		first = y;
	}
	return *this;
}
Chain & Chain::Insert(int i, int x) {
	ChainNode *current = first;
	ChainNode *newNode = new ChainNode;
	newNode->data = x;

	int a = 0;
	while (a < i) {
		current = current->link;
		i++;
	}
	newNode->link = current->link;
	current->link = newNode;
	return *this;
}
int Chain::Find(int x) {
	ChainNode *current;
	int location = 1;
	for (current = first->link; current; current = current->link) {
		if (current->data == x) {

			break;
		}
		else {
			location++;
		}
	}
	if (current) {
		return location;
	}
	else {
		return 0;
	}
}
void Chain::Output(ostream& out) {
	ChainNode *current;
	for (current = first->link; current->link; current = current->link) {
		out << current->data << ",";
	}
	out << current->data << endl;
}
ostream& operator<<(ostream& out, Chain& x) {
	x.Output(out); return out;
}

int main()
{
	cout << "Input1" << endl;
	Chain *temp = new Chain;
	int a = 0;
	while (cin >> a && a != 0) {
		*temp = temp->Append(a);
	}
	cout << "Output1" << endl;
	cout << *temp;
	cout << "Input2" << endl;
	cin >> a;
	*temp = temp->Append(a);
	cout << "Output2" << endl;
	cout << *temp;
	cout << "Input3" << endl;
	cin >> a;
	cout << "Output3" << endl;
	cout << temp->Find(a) << endl;
	cout << "Input4" << endl;
	cin >> a;
	cout << "Output4" << endl;
	cout << temp->Find(a) << endl;
	cout << "Input5" << endl;
	Chain *temp1 = new Chain;

	while (cin >> a && a != 0) {
		*temp1 = temp1->Append(a);
	}
	cout << "Output5" << endl;
	cout << *temp1;
	*temp = temp->Merge(*temp1);
	cout << *temp;
	
	cout << "End" << endl;
	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

运行结果:
在这里插入图片描述

实验四 堆栈的应用

1、 输入一个数学表达式(假定表达式输入格式合法),计算表达式结果并输出。
2、 数学表达式由单个数字和运算符“+”、“-”、“*”、“/”、“(、) ”构成,例如 2 + 3 * ( 4 + 5 ) - 6 / 4。
3、 变量、输出采用整数,只舍不入。

//vs上 执行程序的时候居然将输入法自动换成了中文 存在括号的不同 造成程序运行错误 真是rqgl/+vhl*
#include "pch.h"
#include <iostream>
#include <string>
using namespace std;

template <class T>
class Node {
	public:
		T data;
		Node<T> *link;
};
template <class T>
class LinkedStack {
	public:
		LinkedStack() { topNode = 0; }
		bool IsEmpty()const { return topNode == 0; }
		LinkedStack<T>& PushStack(const T&x);
		LinkedStack<T>& PopStack(T&x);
		LinkedStack<T>& PopStack();
		int Size()const;
		T Top()const;
		Node<T> *topNode;
};
template <class T>
LinkedStack<T>& LinkedStack<T>::PushStack(const T&x) {
	Node<T> *temp = new Node<T>;
	temp->data = x;
	temp->link = topNode;
	topNode = temp;
	return *this;
}
template <class T>
LinkedStack<T>& LinkedStack<T>::PopStack(T& x) {
	x = topNode->data;
	topNode = topNode->link;
	return *this;
}
template <class T>
LinkedStack<T>& LinkedStack<T>::PopStack() {
	topNode = topNode->link;
	return *this;
}

template<class T>
T LinkedStack<T>::Top()const {
	return topNode->data;

}
template <class T>
int LinkedStack<T>::Size()const {
	Node<T> *temp = topNode;
	int count = 0;
	while (temp) {
		count++;
		temp = temp->link;

	}
	return count;
}
int Level(char a) {
	switch (a) {
	case '+':
	case '-':
		return 1;
	case '*':
	case '/':
		return 2;
	case '(':
	case ')':
		return 0;
	case '#':
		return -1;
	}
	return -2;
}
int calculate(int a,int b,char t) {
	switch (t) {
		case '+':
			return a + b;
		case '-':
			return b -a ;
		case '*':
			return a * b;
		case '/':
			return b / a;
		default:
			return 0;
	}
}

int main()
{
	
	cout << "Input" << endl;
	string s=" ";
	cin >> s;
	s += "#";
	int n=0;
	char x;
	int a, b;
	LinkedStack<char> operat;
	LinkedStack<int> number;
	for (int i = 0; i<s.length(); i++) {
		if (s[i] > 47 && s[i]<58) {
			number.PushStack(s[i]-48);
		}
		else {
			if (operat.Size() == 0 || s[i] == '(' || Level(s[i])>Level(operat.Top()) ){
				operat.PushStack(s[i]);
			}else {
				if (s[i] == ')') {
					x = operat.Top();
					operat.PopStack();
					operat.PopStack();
					number.PopStack(a);
					number.PopStack(b);
					n = calculate(a, b, x);
					number.PushStack(n);
				}else {
					x = operat.Top();
					operat.PopStack();
					operat.PushStack(s[i]);
					number.PopStack(a);
					number.PopStack(b);
					n = calculate(a, b, x);
					number.PushStack(n);
				}
			}
		}
	}
	//将堆栈中的剩余计算  计算完毕 
	while (operat.topNode->link!=0) {
		operat.PopStack();
		x = operat.Top();
		number.PopStack(a);
		number.PopStack(b);
		n = calculate(a, b, x);
		number.PushStack(n);
	}
	int result = number.Top();
	cout << "Output\n" << result << endl << "End"<<endl;
}

在这里插入图片描述

实验五 二叉树操作

1、 输入一个完全二叉树的层次遍历字符串,创建这个二叉树,输出这个二叉树的前序遍历字符串、中序遍历字符串、后序遍历字符串、结点数目、二叉树高度(上述每一个结果独立一行显示)。
2、 输入二叉树前序序列和中序序列(各元素各不相同),创建这个二叉树,输出该二叉树的后序序列、层次遍历。
如何实现前序中序 构造二叉树相关信息与链接

#include "pch.h"
#include <iostream>
#include <string>
using namespace std;
template <class T>
class BinaryTreeNode {
	/*friend BinaryTreeNode<T>* CreateTree(string s, int i, int maxlength,T t);
	friend void Visit(BinaryTreeNode<T> *);
	friend void InOrder(BinaryTreeNode<T> *);
	friend void PreOrder(BinaryTreeNode<T> *);
	friend void PostOrder(BinaryTreeNode<T> *);
	friend void LevelOrder(BinaryTreeNode<T> *);*/
	friend int main();
public:
	BinaryTreeNode() { LeftChild = RightChild = 0; }
	BinaryTreeNode(const T& e) {
		data = e;
		LeftChild = RightChild = 0;
	}
	BinaryTreeNode(const T& e, BinaryTreeNode *l, BinaryTreeNode *r) {
		data = e;
		LeftChild = l;
		RightChild = r;
	}

	T data;
	BinaryTreeNode<T> *LeftChild, *RightChild;
};
template <class T>
void Visit(BinaryTreeNode<T> *t, int length, int &b) {
	if (b<length) {
		cout << t->data << ",";
	}
	else {
		cout << t->data<<endl;
	}
	
}
template <class T>
void InOrder(BinaryTreeNode<T> *t,int length,int& b) {
	
	if (t) {

		InOrder(t->LeftChild,length,b);
		Visit(t, length,++b);
		InOrder(t->RightChild, length,b);
	}
	
}
template <class T>
void PreOrder(BinaryTreeNode<T> *t, int length, int& b) {
	if (t) {
		Visit(t, length,++b);
		PreOrder(t->LeftChild, length, b);
		PreOrder(t->RightChild, length, b);
	}
	
}
template <class T>
void PostOrder(BinaryTreeNode<T> *t, int length, int& b) {
	
	if (t) {

		PostOrder(t->LeftChild, length, b);
		PostOrder(t->RightChild, length, b);
		Visit(t, length,++b);
	}
	
}
template <class T1>
class Node {
public :
	Node() { data = 0; next = 0; }
	T1 data;
	Node<T1> *next;
};
template <class T1>
class LinkedQueue {
	public:
		LinkedQueue() { front = rear = 0; }
		bool IsEmpty() const {
			return ((front)? false:true);
		}
		LinkedQueue<T1> & Add(const T1& x) {
			Node<T1> *p = new Node<T1>;
			p->data = x;
			p->next = 0;
			if (front) {
				rear->next = p;

			}
			else {
				front = p;
			}
			rear = p;
			return *this;
		}
		LinkedQueue<T1> & Delete( T1& x) {
			if (IsEmpty()) {
				return *this;
			}
			else {
				x = front->data;
				Node<T1> *p = front;
				front = front->next;
				delete p;
				return *this;
			}

		}
	private:
		Node<T1> *front;
		Node<T1> *rear;

};

template <class T>
void LevelOrder(BinaryTreeNode<T> *t, int length, int& b) {
	LinkedQueue<BinaryTreeNode<T> *> Q;
	
	while (t)
	{
		
		Visit(t, length, ++b);
		if (t->LeftChild) Q.Add(t->LeftChild);
		if (t->RightChild) Q.Add(t->RightChild);

		if (Q.IsEmpty()) {
			return;
		}
		else {
			Q.Delete(t);
		}
		
		
			

		
	}
}
template <class T>
BinaryTreeNode<T>* CreateTree(string s,int i,int maxlength,T t) {
	BinaryTreeNode<T> *node = new BinaryTreeNode<T>(s[i]);
	if (2*i<=maxlength&&2*i+1 <= maxlength) {
		node->LeftChild = CreateTree(s,i*2,maxlength,t);
		node->RightChild= CreateTree(s, i * 2+1, maxlength,t);
	}
	else if (2*i<=maxlength && 2*i+1>maxlength) {
		node->LeftChild = CreateTree(s, i * 2, maxlength,t);

	}
	else {

	}
	return node;
}
template <class T>
BinaryTreeNode<T>* build(BinaryTreeNode<T>* node,int& count,int judge[],string s1,string s2) {
	char t = s1[count++];int i;
	for (i = 0; i <s1.length(); i++) {
		if (t==s2[i]) {
			break;
		}
	}
	judge[i] = 1;
	node = new BinaryTreeNode<char>(t);
	if (i>0&&(i<s1.length())&&judge[i-1]!=1) {
		node->LeftChild = build(node->LeftChild,count,judge,s1,s2);
	}
	if (i >= 0 && i < (s1.length()-1) && judge[i +1] != 1) {
		node->RightChild = build(node->RightChild, count, judge, s1, s2);
	}
	return node;
}
int main()
{
	
	
	
	cout << "Input1" << endl;
	string s ="0";
	string s1 = " ";
	cin >> s1;
	s = s + s1;
	char a = 'a';
	BinaryTreeNode<char> *root = new BinaryTreeNode<char>();
	root = CreateTree(s,1,s.length()-1,a);
	cout << "Output1" << endl;
	int b = 0;
	PreOrder(root, s.length() - 1,b); 
	InOrder(root, s.length() - 1, b=0);
	PostOrder(root, s.length() - 1, b=0); 
	cout << s.length() - 1 << endl;
	int height = 0;
	BinaryTreeNode<char> *temp = root;
	while (temp!=0) {
		height++;
		temp = temp->LeftChild;
	}
	cout << height << endl;
	cout << "Input2" << endl;
	string s2 = " ";
	cin >> s1;
	cin >> s2;
	int count = 0;
	BinaryTreeNode<char> *root1 = new BinaryTreeNode<char>();
	int judge[100] = { 0,0,0,0 };
	root1 = build(root1,count,judge,s1,s2);

	cout << "Output2" << endl;
	PostOrder(root1, s1.length(), b = 0);
	LevelOrder(root1, s1.length(), b = 0);
	cout << "End" << endl;
	return 0;
}

在这里插入图片描述

实验六 堆和搜索树

1、 输入一系列不为零的正整数(最多不超过20个),遇到0代表输入结束(不包含0)。
2、 根据上面输入的数据序列,用初始化方法创建最大堆(不要用节点依次插入的办法创建最大堆),然后输出最大堆的层次序列。
3、 输出用堆排序后的排序结果。
4、 根据上面输入的数据,创建二叉搜索树(关键字不允许重复,如遇重复,则不重复插入该关键字),输出二叉搜索树的前序序列、中序序列(分行输出)。

#include <iostream>
using namespace std;

template <class T>
class BinaryTreeNode {
	/*friend BinaryTreeNode<T>* CreateTree(string s, int i, int maxlength,T t);
	friend void Visit(BinaryTreeNode<T> *);
	friend void InOrder(BinaryTreeNode<T> *);
	friend void PreOrder(BinaryTreeNode<T> *);
	friend void PostOrder(BinaryTreeNode<T> *);
	friend void LevelOrder(BinaryTreeNode<T> *);*/
	friend int main();
public:
	BinaryTreeNode() { LeftChild = RightChild = 0; }
	BinaryTreeNode(const T& e) {
		data = e;
		LeftChild = RightChild = 0;
	}
	BinaryTreeNode(const T& e, BinaryTreeNode *l, BinaryTreeNode *r) {
		data = e;
		LeftChild = l;
		RightChild = r;
	}

	T data;
	BinaryTreeNode<T> *LeftChild, *RightChild;
};
template <class T>
void Visit(BinaryTreeNode<T> *t, int length, int &b) {
	if (b < length) {
		cout << t->data << ",";
	}
	else {
		cout << t->data << endl;
	}

}
template <class T>
void InOrder(BinaryTreeNode<T> *t, int length, int& b) {

	if (t) {

		InOrder(t->LeftChild, length, b);
		Visit(t, length, ++b);
		InOrder(t->RightChild, length, b);
	}

}
template <class T>
void PreOrder(BinaryTreeNode<T> *t, int length, int& b) {
	if (t) {
		Visit(t, length, ++b);
		PreOrder(t->LeftChild, length, b);
		PreOrder(t->RightChild, length, b);
	}

}
template <class T>
void PostOrder(BinaryTreeNode<T> *t, int length, int& b) {

	if (t) {

		PostOrder(t->LeftChild, length, b);
		PostOrder(t->RightChild, length, b);
		Visit(t, length, ++b);
	}

}
template <class T>
BinaryTreeNode<T>* CreateTree(string s, int i, int maxlength, T t) {
	BinaryTreeNode<T> *node = new BinaryTreeNode<T>(s[i]);
	if (2 * i <= maxlength && 2 * i + 1 <= maxlength) {
		node->LeftChild = CreateTree(s, i * 2, maxlength, t);
		node->RightChild = CreateTree(s, i * 2 + 1, maxlength, t);
	}
	else if (2 * i <= maxlength && 2 * i + 1 > maxlength) {
		node->LeftChild = CreateTree(s, i * 2, maxlength, t);

	}
	else {

	}
	return node;
}

template <class E,class K>
class BSTree {
public :
	BSTree(){
		root = 0;
	}
	bool Search(const K& k, E& e) const;
	BSTree<E, K>& Insert(const E& e,int &size);
	BinaryTreeNode<E> *root;
};
template <class E, class K>
bool BSTree<E,K>::Search(const K& k, E& e) const {
	BinaryTreeNode<E> *p = root;
	while (p) {
		if (k < p->data)p = p->LeftChild;
		else if (k > p->data)p = p->RightChild;
		else { e = p->data; return true; }
	}
	return false;
}
template <class E, class K>
BSTree<E, K>& BSTree<E, K>::Insert(const E& e,int &size){
	BinaryTreeNode<E> *p = root;
	BinaryTreeNode<E> *pp = 0;
	while (p) {
		pp = p;
		if (e < p->data)p = p->LeftChild;
		else if (e> p->data)p = p->RightChild;
		else { size = size - 1; return *this; }
	}
	BinaryTreeNode<E> *r = new BinaryTreeNode<E>(e);
	if (root) {
		if (e < pp->data)pp->LeftChild = r;
		else pp->RightChild = r;
	}
	else root = r;

	return *this;
}
template <class T>
class MaxHeap {
public:
	MaxHeap(int MaxHeapSize = 10);
	int Size()const{return CurrentSize;}
	T Max() {
		if (CurrentSize == 0) { return -1; }
		else { return heap[0]; }
	}
	MaxHeap<T>& Insert(const T& x);
	MaxHeap<T>& Delete(T& x);
	void Initialize(T a[], int size, int ArraySize);
	void Output() {
		int i = 1;
		while (i <= CurrentSize) {
			if (i!=CurrentSize) {
				cout << heap[i] << ",";
				i++;
			}
			else {
				cout <<heap[i] << endl;
				i++;
			}
			
		}
	}
	void HeapSort(T a[], int n);
	void changeCurrentsize(int a) {
		CurrentSize = a;
	}
private:
	int CurrentSize, MaxSize;
	T *heap;

};
template <class T>
MaxHeap<T>::MaxHeap(int MaxHeapSize) {
	MaxSize = MaxHeapSize;
	heap = new T[MaxSize + 1];
	CurrentSize = 0;
}
template <class T>
MaxHeap<T>& MaxHeap<T>::Insert(const T& x) {
	if (CurrentSize == MaxSize) {
		return *this;
	}else {
		int i = ++CurrentSize;
		while (i != 1 && x > heap[i / 2]) {
			heap[i] = heap[i / 2];
			i /= 2;
		}
		heap[i] = x;
		return *this;
	}

	
}
template <class T>
MaxHeap<T>& MaxHeap<T>::Delete(T& x) {
	if (CurrentSize==0) {
		return *this;
	}
	else {
		x = heap[1];
		T y = heap[CurrentSize--];
		int i = 1,
		ci = 2;
		while (ci <= CurrentSize) {
			if (ci < CurrentSize&&heap[ci] < heap[ci + 1]) ci++;
			if (y >= heap[ci]) break;
			heap[i] = heap[ci];
			i = ci;
			ci *= 2;
		}
		heap[i] = y;
	}


	return *this;
}
template <class T>
void MaxHeap<T>::Initialize(T a[], int size, int ArraySize) {
	delete[] heap;
	heap = a;
	CurrentSize = size;
	MaxSize = ArraySize;
	for (int i = CurrentSize / 2; i >= 1;i--) {
		T y = heap[i];
		int c = 2 * i;
		while (c <= CurrentSize) {
			if (c < CurrentSize&&heap[c] < heap[c + 1]) c++;
			if (y >= heap[c])break;
			heap[c / 2] = heap[c];
			c *= 2;

		}
		heap[c / 2] = y;
	}
}
template<class T>
void MaxHeap<T>::HeapSort(T a[], int n) {
	MaxHeap<T> H(1);
	H.Initialize(a, n, n);
	T x;
	for (int i = n - 1; i >=1 ; i--) {
		H.Delete(x);
		a[i + 1] = x;
	}
}
int main()
{
	cout << "Input" << endl;
	int a[20] = { 0,0 };
	int i = 1; cin >> a[i]; 
	while (a[i]!=0) {
		i++;
		cin >> a[i];
		
	}
	int size = i - 1;
	int c[20] = { 0,0 };
	for (int g = 0; g < 20; g++) {
		c[g] = a[g];
	}
	MaxHeap<int> *maxheap = new MaxHeap<int>(20);
	maxheap->Initialize(a,size,20);
	cout << "Output" << endl;
	maxheap->Output();
	int b[20] = { 0,0 };
	for (int j = 0; j < 20;j++) {
		b[j] = a[j];
	}
	
	MaxHeap<int> *maxheap1 = new MaxHeap<int>(size);
	maxheap1->HeapSort(b,size);
	maxheap1->changeCurrentsize(size);
	for (int k = 0; k < size-1; k++) {
		cout << b[k + 1] << ",";
	}
	cout << b[size] << endl;
	BSTree<int, int> *bstree = new BSTree<int, int>();
	for (int l = 1; l <= size;l++) {
		bstree->Insert(c[l],size);
	}
	int y = 0;
	
PreOrder(bstree->root,size,y=0);
	InOrder(bstree->root, size,y=0);
	
	
	cout << "End"<<endl;
	return 0;
}

在这里插入图片描述

实验七:图的操作

1、 创建图类,存储结构使用邻接矩阵。
2、 输入图的节点数n(不超过10个)、边数m,节点分别用1-n代表。
3、 采用“起始节点,终止节点,权值”输入图的m条边,创建图。
4、 输出从节点1开始的BFS遍历,要求小的节点在前大的在后。
5、 输出从节点1开始的DFS遍历,要求小的节点在前大的在后。
6、 输出从第1节点到第n节点最短路径的长度,如果没有路经,输出0。

#include "pch.h"
#include <iostream>
using namespace std;
template<class T>
class ChainNode {
	
public:
	T data;
	ChainNode<T> *link;
};
template<class T>
class Chain {
public:
	Chain() { first = 0; }
	bool IsEmpty()const { return first == 0; }
	Chain<T> & Delete(int k,T& x);
	Chain<T> & Insert(int k, const T&x);

	ChainNode<T> *first;
};
template<class T>
class ChainIterator {
public:
	T* Initialize(const Chain<T> & c) {
		location = c.first;
		if (location)return &location->data;
		return 0;
	}
	T* Next() {
		if (!location)return 0;
		location = location->link;
		if (location)return &location->data;
		return 0;
	}

private:
	ChainNode < T> *location;
};


template <class T1>
class Node {
public:
	Node() { data = 0; next = 0; }
	T1 data;
	Node<T1> *next;
};
template <class T1>
class LinkedQueue {
public:
	LinkedQueue() { front = rear = 0; }
	bool IsEmpty() const {
		return ((front) ? false : true);
	}
	LinkedQueue<T1> & Add(const T1& x) {
		Node<T1> *p = new Node<T1>;
		p->data = x;
		p->next = 0;
		if (front) {
			rear->next = p;

		}
		else {
			front = p;
		}
		rear = p;
		return *this;
	}
	LinkedQueue<T1> & Delete(T1& x) {
		if (IsEmpty()) {
			return *this;
		}
		else {
			x = front->data;
			Node<T1> *p = front;
			front = front->next;
			delete p;
			return *this;
		}

	}
private:
	Node<T1> *front;
	Node<T1> *rear;

};


template<class T>
void Make2DArray(T** &x,int rows,int cols) {
	x = new T *[rows];
	for (int i = 0; i < cols;i++) {
		x[i] = new int[cols];
	}
}
template <class T>
class AdjacencyWDigraph {
	
public:
	AdjacencyWDigraph(int Vertices=10,T noEdge=0);
	bool Exist(int i,int j)const;
	int Edges()const { return e; }
	int Vertices() const { return n; }
	AdjacencyWDigraph<T> & Add(int i, int j, const T& w);
	AdjacencyWDigraph<T> & Delete(int i, int j);
	int Degree(int i)const;
	void Initialize() { pos = new int[n + 1]; }
	void DeactivatePos() { delete[] pos; }
	int Begin(int i,int reach[]);
	int NextVertes(int i);
	void BFS(int v, int reach[], int label);
	void DFS(int v, int reach[], int label,int& pp,int ans[]);
	T ShortestPaths(int s, T d[], int p[]);
	bool findPath(int v, int w, int reach[], int label);
	int findTheShortestPath(int begin, int end);
	bool dandiaodian() {
		bool flag = true;
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n;j++) {
				if (a[i][j]!=NoEdge) {
					flag = false;
				}

			}
			if (flag == true) {
				return flag;
			}
			else {
				flag = true;
			}
		}
		flag = false;
		return flag;

	}
private:
	T NoEdge;
	int n;
	int e;
	T **a;
	int *pos;
};
template<class T>

bool AdjacencyWDigraph<T>::findPath(int v, int w, int reach[], int label)

{// 实际搜索v到w的路径,其中v != w.// 按深度优先方式搜索一条路径

	reach[v] = label;

	int u = Begin(v,reach);

	while (u) {

		if (reach[u] != label) {

			if (u == w) return true;

			if (findPath(u, w, reach, label))

				return true;

		}
		u = NextVertes(v);

	}
	return false;

}



int findMIN(int a[], int length) {

	int min = a[0];

	int positionOfMin = 0;

	for (int i = 1; i <= length; i++)

	{

		if (a[i] <= min) {

			min = a[i];

			positionOfMin = i;

		}

	}

	return positionOfMin;

}



template<class T>

int AdjacencyWDigraph<T>::findTheShortestPath(int begin, int end)

{

	const int MAX = 9999;

	const int Label = 999;

	int *Dijkstra = new int[end + 1];

	int weightOfPath = 0;

	int positionOfMin = 0;

	for (int i = 0; i < end + 1; i++)

	{

		Dijkstra[i] = MAX;

	}



	Dijkstra[begin] = 0;



	int *reach = new int[end + 1];

	if (findPath(begin, end, reach, Label)) //如果存在从begin 到end 的通路

	{

		while (Dijkstra[end] != Label)

		{

			positionOfMin = findMIN(Dijkstra, end);

			weightOfPath = Dijkstra[positionOfMin];

			Dijkstra[positionOfMin] = Label;

			for (int i = 1; i < end + 1; i++)

			{

				if (Dijkstra[i] != Label && a[positionOfMin][i] != NoEdge && a[positionOfMin][i] + weightOfPath < Dijkstra[i]) //如果没走过 且 其上一步走到的地方的临边存在 且 它的值加上之前走过的比直接到此处路途更短 就更新一遍表

				{

					Dijkstra[i] = a[positionOfMin][i] + weightOfPath;

				}

			}



		}



	}

	return weightOfPath;

}

template <class T>
AdjacencyWDigraph<T>::AdjacencyWDigraph(int Vertices, T noEdge) {
	Initialize();
	n = Vertices;
	e = 0;
	NoEdge = noEdge;
	Make2DArray(a,n+1,n+1);
	for (int i = 1; i <= n;i++) {
		for (int j = 1; j <= n;j++) {
			a[i][j] = NoEdge;
		}
	}
}
template <class T>
bool AdjacencyWDigraph<T>::Exist(int i,int j)const {
	if (i<1||j<1||i>n||j>n||a[i][j]==NoEdge) {
		return false;
	}
	else {
		return true;
	}
}
template <class T>
AdjacencyWDigraph<T>& AdjacencyWDigraph<T>::Add(int i,int j,const T& w) {
	if (i<1 || j<1 || i>n || j>n || i == j || a[i][j] != NoEdge) return *this;
	a[i][j] = w;
	a[j][i] = w;
	e++;
	return *this;
}
template <class T>
AdjacencyWDigraph<T>& AdjacencyWDigraph<T>::Delete(int i,int j) {
	if (i<1 || j<1 || i>n || j>n || a[i][j] == NoEdge) return *this;
	a[i][j] = NoEdge;
	a[j][i] = NoEdge;
	e--;
	return *this;

}
template <class T>
int  AdjacencyWDigraph<T>::Degree(int i)const {
	if (i<1||i>n) {
		return 0;
	}
	int sum = 0;
	for (int j = 1; j <= n;j++) {
		if (a[i][j] != NoEdge)sum++;

	}
	return sum;
}

template<class T>
int AdjacencyWDigraph<T>::Begin(int i,int reach[])
{
	if (i<1 || i>n) return 0;
	for (int j = 1; j <= n; j++) {
		if (a[i][j] != NoEdge&&reach[j]!=1) {
			pos[i] = j;
			return j;
		}
	}
	pos[i] = n + 1;
	return 0;
	
}

template<class T>
int AdjacencyWDigraph<T>::NextVertes(int i)
{

	if (i<1 || i>n) return 0;
	for (int j = pos[i]+1; j <= n; j++) {
		if (a[i][j] != NoEdge) {
			pos[i] = j;
			return j;
		}
	}
	pos[i] = n + 1;
	return 0;
}

template<class T>
void AdjacencyWDigraph<T>::BFS(int v, int reach[], int label)
{
	LinkedQueue<int> Q;
	reach[v] = label;
	Q.Add(v);
	while (!Q.IsEmpty()) {
		int w; Q.Delete(w);
		
		for (int u = 1; u <= n; u++) {
			if (a[w][u] != NoEdge&&!reach[u]) {
				Q.Add(u);
				reach[u] = label;

			}
		}
		if (Q.IsEmpty()) {
			cout << w << endl;
		}
		else {
			cout << w << ",";
		}
	}
	
}

template<class T>
void AdjacencyWDigraph<T>::DFS(int v, int reach[], int label,int& pp,int ans[])
{
	reach[v] = label;
	ans[pp++] = v;
	int u = Begin(v,reach);
	while (u) {
		DFS(u,reach,label,pp,ans);
		u = NextVertes(v);
	}
	
}

template<class T>
T AdjacencyWDigraph<T>::ShortestPaths(int s, T d[], int p[])
{
	int meiyong = 0;
	if (s<1 || s>n)return 0;
	Chain<int> L;
	ChainIterator<int> l;
	for (int i = 1; i <= n; i++) {
		d[i] = a[s][i];
		if (d[i] == NoEdge)p[i] = 0;
		else {
			p[i] = s;
			L.Insert(0, i);
		}
	}
	while (!L.IsEmpty()) {
		int *v = l.Initialize(L);
		int *w = l.Next();
		while (w) {
			if (d[*w] < d[*v])v = w;
			w = l.Next();
		}
		int i = *v;
		L.Delete(*v,meiyong);
		for (int j = 1; j <= n; j++) {
			if (a[i][j] != NoEdge && (!p[j] || d[j] > d[i] + a[i][j])) {
				d[j] = d[i] + a[i][j];
				if (!p[j]) {
					L.Insert(0, j);
				}
				else {
					p[j] = i;
				}
			}
		}
	}
	return d[n];
}

int main()
{
	cout << "Input" << endl;
	int i = 0, j = 0, w = 0, edge = 0, num = 0;
	char a = ' ';
	cin >> i; cin >> a; cin >> edge;
	num = i;
	int b[20] = { 0,0 };
	AdjacencyWDigraph<int> *awdg = new AdjacencyWDigraph<int>(i,500);
	for (int k = 1; k <= edge;k++) {
		cin >> i >> a >> j >> a >> w;
		awdg->Add(i,j,w);
	}
	//cout << awdg->Edges();
	cout << "Output" << endl;
	awdg->BFS(1,b,1);
	int pp = 1;
	int c[20] = { 0,0 };
	int ans[20] = { 0,0 };
	awdg->DFS(1, c,1,pp=0,ans);
	if (awdg->dandiaodian()) {
		for (int l = 0; l < num - 2; l++) {
			cout << ans[l] << ",";
		}cout << ans[num - 2] << endl;
	}
	else {
		for (int l = 0; l < num-1;l++) {
		cout << ans[l] << ",";
	}cout << ans[num - 1] << endl;
	}
	
	
	int p[30] = { 0,0 };
	int d[30] = { 0,0 };
	int r = awdg->findTheShortestPath(1,num);
	cout << r << endl;

	cout << "End"<<endl;
	return 0;
}


// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

template<class T>
Chain<T>& Chain<T>::Delete(int k, T & x)
{
	if (k<1||!first) {
		return *this;
	}
	ChainNode<T> *p = first;
	if (k==1) {
		first = first->link;
	}
	else {
		ChainNode<T> *q = first;
		for (int index = 1; index < k - 1 && q; index++) {
			q = q->link;
		}
		if (!q || !q->link)return *this;
		p = q->link;
		q->link = p->link;
	}
	x = p->data;
	delete p;
	return *this;

	// TODO: 在此处插入 return 语句
}

template<class T>
Chain<T>& Chain<T>::Insert(int k, const T & x)
{
	if (k < 0)return *this;
	ChainNode<T> *p = first;
	for (int index = 1; index < k&&p; index++) {
		p = p->link;
	}
	if (k > 0 && !p)return *this;
	ChainNode<T> *y = new ChainNode<T>;
	y->data = x;
	if (k) {
		y->link = p->link;
		p->link = y;
	}
	else {
		y->link = first;
		first = y;

	}
	return *this;
	// TODO: 在此处插入 return 语句
}



在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值