+## 实验一 递归练习
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&¤t2; ) {
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 语句
}