某末流学校计算机学院和网络空间安全学院数据结构作业
Buchiyexiao
作业一
Fibonacci数列
/*
编写递归函数计算Fibonacci数列,能避免重复计算
输入:
input.txt,仅包含一个整数n(0-90)
输出:
程序应能检查输入合法性,若有错误,输出错误提示“WRONG”;否则输出F(n)。两种情况都输出一个回车(形成一个空行)。所有实例均应在30秒内输出结果
ps.可用一数组保存Fibonacci数列,用一个特殊值表示还未计算出Fibonacci数
递归调用前先检查数组,若已计算,直接取用,不进行递归调用;若未计算,调用递归函数,计算完成后保存入数组
实际上,这种方法得到了F(1)-F(n),而不仅是F(n)
另外,注意数据类型取值范围问题。VC 6.0中,长整型为LONGLONG,而其输出用%I64d
*/
#include<iostream>
#include<fstream>
using namespace std;
long long temp[150];
long long fun(int n)
{
if(n<3)
{
return 1;
}
if(temp[n]>0)
{
return temp[n];
}
temp[n] = fun(n-1) + fun(n-2);
return temp[n];
}
int main()
{
int num;
ifstream infile("input.txt");
infile>>num;
infile.close();
if(num>90||num<0)
{
cout<<"Wrong!"<<endl;
}
else if(num==0)
{
cout<<"0"<<endl;
}
else
{
printf("%I64d",fun(num));
cout<<endl;
}
system("pause");
return 0;
}
子集全集输出
/*
2.编写递归函数,求n个元素集合的所有子集。不妨令集合元素为小写字母,原集合为{‘a’, ‘b’, …, ‘a’ + n - 1}
输入:
input.txt,仅包含整数n(1-26)
输出:
若输入合法,输出集合的所有子集;否则输出“WRONG”
子集输出格式为每行一个子集,空集用空行表示,非空集合每个元素间用一个空格间隔,最后一个元素之后不能有空格
例如,对n=3,可能的输出为:
―――――――――――
a
a b
a b c
a c
b
b c
c
――――――――――――
*/
#include<iostream>
#include<fstream>
using namespace std;
void print(char *a,bool *b,int cur,int n)
{
if(cur==n)
{
for(int i=0;i<n;i++)
{
if(b[i])
{
if(i==n-1)
{
cout<<a[i];
}
else
{
cout<<a[i]<<" ";
}
}
}
cout<<endl;
}
else
{
b[cur] = true;
print(a,b,cur + 1,n);
b[cur] = false;
print(a,b,cur + 1,n);
}
}
int main()
{
int num;
ifstream infile("input.txt");
infile>>num;
infile.close();
char a[26];
for(int i=0;i<26;i++)
{
a[i] = 'a' + i;
}
bool *b = new bool(num);
print(a,b,0,num);
return 0;
}
作业二
作业二代码在检查完之后整理过程中不小心删除了,然后清了回收站,不过作业二是针对链表的题目,并不难
作业三
Transpose方法对于三角矩阵
/*
扩充类lowerTriangularMatrix,增加矩阵转置方法
该方法返回值是上三角矩阵,为下三角矩阵的转置矩阵,是类upperTriangularMatrix的一个实例
并确定其时间复杂度
*/
#include<iostream>
using namespace std;
template <class T>
class upperTriangularMatrixs
{
private:
int n;
T *t;
public:
upperTriangularMatrixs(int s)
{
n = s;
t = new T[n*(n + 1) / 2];
for (int i = 0; i < n*(n + 1) / 2; i++)
{
t[i] = 1;
}
}
/*
~upperTriangularMatrixs()
{
delete[]t;
}
*/
void set(int x, int y, const T& item)
{
if (x <= 0 || y <= 0 || x > n || y > n)
{
cout << "越界" << endl;
return;
}
if (y < x&&item != 0)
{
cout << "下三角为零" << endl;
return;
}
t[((x - 1)*(n + n - x + 2) / 2) + y - x] = item;
//前x-1行用高斯定理,最后第x行做减法
}
void get(int x, int y, T& item)
{
if (x <= 0 || y <= 0 || x > n || y > n)
{
cout << "越界" << endl;
return;
}
if (y < x)
{
item = 0;
return;
}
item = t[((x - 1)*(n + n - x + 2) / 2) + y - x];
}
void input()
{
for (int i = 1; i <= n; i++)
{
for (int j = i; j <= n; j++)
{
T temp;
cin >> temp;
this->set(i, j, temp);
}
}
}
void output()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
T temp;
this->get(i, j, temp);
cout << temp << " ";
}
cout << endl;
}
}
};
template <class T>
class lowerTriangularMatrixs
{
private:
int n;
T *t;
public:
lowerTriangularMatrixs(int s)
{
n = s;
t = new T[n*(n + 1) / 2];
for (int i = 0; i < n*(n + 1) / 2; i++)
{
t[i] = 1;
}
}
/*
lowerTriangularMatrixs()
{
delete[]t;
}
*/
void set(int x, int y, T item)
{
if (x <= 0 || y <= 0 || x > n || y > n)
{
cout << "越界" << endl;
return;
}
if (y > x&&item != 0)
{
cout << "上三角为零" << endl;
return;
}
t[(x - 1)*x / 2 + y - 1] = item;
}
void get(int x, int y, T& item) {
if (x <= 0 || y <= 0 || x > n || y > n)
{
cout << "越界" << endl;
return;
}
if (y > x)
{
item = 0;
return;
}
item = t[(x - 1)*x / 2 + y - 1];
}
void input()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
T temp;
cin >> temp;
this->set(i, j, temp);
}
}
}
void output()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
T temp;
this->get(i, j, temp);
cout << temp << " ";
}
cout << endl;
}
}
upperTriangularMatrixs<T> trans()
{
upperTriangularMatrixs<T> m(this->n);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
T temp;
this->get(i, j, temp);
m.set(j, i, temp);
}
}
return m;
}
};
int main()
{
lowerTriangularMatrixs<int> a(4);
a.input();
cout << endl;
a.output();
cout << endl;
upperTriangularMatrixs<int> b(4);
b = a.trans();
cout << endl;
b.output();
system("pause");
return 0;
}
multiply方法对于稀疏矩阵
/*
编写一个方法,把两个储存在一位数组的稀缺矩阵相乘
ps.假定两个矩阵和结果矩阵都是按行主次序存储
*/
#include<iostream>
using namespace std;
template <class T>
class elem {
public:
int x;
int y;
T item;
elem(int i = 0, int j = 0, T t = 0)
{
x = i;
y = j;
item = t;
}
bool operator < (elem<T> target)
{
if (x > target.x || (x == target.x&& y >= target.y))
return false;
else
return true;
}
bool operator > (elem<T> target) {
if (x < target.x || (x == target.x&& y <= target.y))
return false;
else
return true;
}
void operator = (elem<T> t)
{
this->x = t.x;
this->y = t.y;
this->item = t.item;
}
};
template<class T>
class sparseMatrix {
private:
int xs;
int ys;
int now;
int max;
elem<T> *items;
public:
//构造构造构造constconst
sparseMatrix(int a = 0, int b = 0, int c = 0)
{
xs = a;
ys = b;
max = c;
now = 0;
if (c != 0)
{
items = new elem<T>[max];
}
else
{
items = NULL;
}
}
sparseMatrix(sparseMatrix<T> const &m)
{
delete[]items;
this->xs = m.xs;
this->ys = m.ys;
this->max = m.max;
this->now = m.now;
this->items = new elem<T>[max];
for (int k = 0; k < now; k++)
{
this->items[k] = m.items[k];
}
}
~sparseMatrix()
{
delete[]items;
}
bool get(int x, int y, T &target)
{
for (int k = 0; k < now; k++)
{
if (items[k].x == x && items[k].y == y)
{
target = items[k].item;
return true;
}
}
return false;
}
bool set(int x, int y, T target)
{
elem<T> t(x, y, target);
for (int k = 0; k < now; k++)
{
if (items[k].x == x && items[k].y == y)
{
items[k].item = target;
return true;
}
}
if (now < max) {
int k;
for (k = 0; k < now; k++)
{
if (items[k]<t&&items[k + 1]>t)
break;
}
for (int j = k; j < now; j++)
{
items[j + 1] = items[j];
}
items[k] = t;
now++;
return true;
}
else {
cout << "非稀疏矩阵" << endl;
return false;
}
}
void input() {
int n;
cout << "items number: ";
cin >> n;
for (int k = 0; k < n; k++) {
int i, j;
T t;
cin >> i >> j >> t;
this->set(i, j, t);
}
}
void output() {
for (int i = 1; i <= xs; i++)
{
for (int j = 1; j <= ys; j++)
{
T temp;
if (this->get(i, j, temp))
cout << temp << " ";
else
cout << 0 << " ";
}
cout << endl;
}
}
sparseMatrix<T> operator *(sparseMatrix<T> &m)
{
if (this->ys == m.xs)
{
sparseMatrix<T> result(this->xs, m.ys, this->xs* m.ys);
for (int i = 1; i <= result.xs; i++)
{
for (int j = 1; j <= result.ys; j++)
{
bool isempty = 1;
T target = 0;
for (int k = 1; k <= this->ys; k++)
{
T elem1, elem2;
if (this->get(i, k, elem1) && m.get(k, j, elem2))
{
target += elem1 * elem2;
isempty = 0;
}
}
if (!isempty) {
result.set(i, j, target);
}
}
}
cout << endl;
return result;
}
else {
cout << "不能相乘" << endl;
sparseMatrix<T> result(0, 0, 0);
return result;
}
}
void operator = (sparseMatrix<T> m)
{
delete[]items;
this->xs = m.xs;
this->ys = m.ys;
this->max = m.max;
this->now = m.now;
this->items = new elem<T>[max];
for (int k = 0; k < now; k++)
{
this->items[k] = m.items[k];
}
}
};
int main()
{
int i, j, k;
cout << "行,列,最大数目" << endl;
cin >> i >> j >> k;
sparseMatrix<int> m(i, j, k);
m.input();
m.output();
cout << "行,列,最大数目" << endl;
cin >> i >> j >> k;
sparseMatrix<int> m1(i, j, k);
m1.input();
m1.output();
cout << "矩阵乘法" << endl;
sparseMatrix<int> m2 = m * m1;
m2.output();
system("pause");
return 0;
}
linkedMatrix的相关函数
/*
给类linkedMatrix增加下列操作:
1)已知一个元素的行数列数与数值,存储这个元素
2)已知一个元素的行和列,从矩阵中取出这个元素
3)两个稀疏矩阵相加
4)两个稀疏矩阵相减
5)两个稀疏矩阵相乘
*/
#include<iostream>
using namespace std;
template <class T>
class Node
{
public:
int x;
int y;
T data;
Node *next;
Node(int a = 0,int b = 0, T t = 0)
{
x = a;
y = b;
data = t;
next = NULL;
}
Node(Node<T> &t)
{
x = t.x;
y = t.y;
data = t.data;
next = t.next;
}
bool operator > (Node<T> t)
{
if (x < t.x || (x == t.x&&y <= t.y))
return false;
else
return true;
}
bool operator < (Node<T> t)
{
if (x > t.x || (x == t.x&&y >= t.y))
return false;
else
return true;
}
bool operator == (Node<T> t)
{
if (x == t.x&&y == t.y)
return true;
else
return false;
}
void operator = (Node<T> t)
{
x = t.x;
y = t.x;
this.data = t.data;
this.next = t.next;
}
};
template <class T>
class linkedMatrixs
{
public:
int xs;
int ys;
Node<T> *head;
linkedMatrixs(int a = 0, int b = 0)
{
xs = a;
ys = b;
head = NULL;
}
linkedMatrixs(linkedMatrixs<T> const &m)
{
if (head != NULL)
clear();
xs = m.xs;
ys = m.ys;
Node<T>* temp = m.head;
while (temp != NULL)
{
this->set(temp->x, temp->y, temp->data);
temp = temp->next;
}
}
~linkedMatrixs()
{
clear();
}
void clear()
{
Node<T>* temp = head;
while (temp != NULL)
{
head = head->next;
delete temp;
temp = head;
}
}
bool get(int x, int y, T&target)
{
Node<T>* temp = head;
while (temp != NULL)
{
if (temp->x == x && temp->y == y)
{
target = temp->data;
break;
}
temp = temp->next;
}
if (temp == NULL)
return false;
else
return true;
}
void set(int x, int y, T target)
{
Node<T>*temp = new Node<T>(x, y, target);
if (head == NULL)
{
head = temp;
return;
}
if ((*temp) < (*head))
{
temp->next = head;
head = temp;
return;
}
Node<T>*curr = head;
while (curr != NULL)
{
if ((*curr) == (*temp))
{
curr->data = target;
return;
}
if (curr->next == NULL && (*curr) < (*temp))
{
curr->next = temp;
return;
}
if ((*curr) < (*temp) && (*(curr->next)) > (*temp))
{
temp->next = curr->next;
curr->next = temp;
return;
}
curr = curr->next;
}
}
void operator = (linkedMatrixs<T> &m)
{
xs = m.xs;
ys = m.ys;
if (head != NULL)
clear();
Node<T>* temp = m.head;
while (temp != NULL)
{
this->set(temp->x, temp->y, temp->item);
temp = temp->next;
}
}
linkedMatrixs<T> operator + (linkedMatrixs<T> &m)
{
linkedMatrixs<T> result;
if (xs != m.xs || ys != m.ys)
{
cout << "行列不对应" << endl;
return result;
}
result.xs = xs;
result.ys = ys;
for (int i = 1; i <= xs; i++)
{
for (int j = 1; j <= ys; j++)
{
T temp1 = 0, temp2 = 0;
this->get(i, j, temp1);
m.get(i, j, temp2);
if (temp1 + temp2 != 0)
result.set(i, j, temp1 + temp2);
}
}
return result;
}
linkedMatrixs<T> operator - (linkedMatrixs<T> &m)
{
linkedMatrixs<T> result;
if (xs != m.xs || ys != m.ys)
{
cout << "行列不对应" << endl;
return result;
}
result.xs = xs;
result.ys = ys;
for (int i = 1; i <= xs; i++)
{
for (int j = 1; j <= ys; j++)
{
T temp1 = 0, temp2 = 0;
this->get(i, j, temp1);
m.get(i, j, temp2);
if (temp1 - temp2 != 0)
result.set(i, j, temp1 - temp2);
}
}
return result;
}
linkedMatrixs<T> operator * (linkedMatrixs<T> &m)
{
linkedMatrixs<T> result;
if (this->ys != m.xs)
{
cout << "行列不对应" << endl;
return result;
}
result.xs = ys;
result.ys = m.xs;
for (int i = 1; i <= result.xs; i++)
{
for (int j = 1; j <= result.ys; j++)
{
T temp = 0;
for (int k = 1; k <= this->ys; k++)
{
T item1, item2;
if (this->get(i, k, item1) && m.get(k, j, item2))
{
temp += item1 * item2;
}
}
if (temp != 0)
{
result.set(i, j, temp);
}
}
}
return result;
}
void input()
{
for (int i = 1; i <= xs; i++)
{
for (int j = 1; j <= ys; j++)
{
T temp;
cin >> temp;
if (temp != 0)
{
set(i, j, temp);
}
}
}
}
void output()
{
for (int i = 1; i <= xs; i++)
{
for (int j = 1; j <= ys; j++)
{
T temp;
if (get(i, j, temp))
{
cout << temp << " ";
}
else
{
cout << 0 << " ";
}
}
cout << endl;
}
}
};
int main()
{
int rr, ww;
cout << "行,列" << endl;
cin >> rr >> ww;
linkedMatrixs<int>m(rr, ww), m1(rr, ww);
m.input();
m1.input();
cout << endl;
linkedMatrixs<int> m2(m + m1);
m2.output();
linkedMatrixs<int> m3(m - m1);
cout << endl;
m3.output();
linkedMatrixs<int> m4(m * m1);
cout << endl;
m4.output();
system("pause");
return 0;
}
作业四
josephus问题
/*
josephus问题
n个人围坐成一圈,按顺序编号为1-n,确定一个整数m,从1号开始数数,每数到第m个人出列,剩下的人从下一个人重新开始数,直至只剩下一个人为止
编写程序,对任意输入的n和m,求出最后剩下的人的编号。要求利用线性表保存这n个人,用公式化描述方法实现
输入:
input.txt,两个整数n(3-100),m(1-m)
输出:
若输入合法,按出列顺序输出人的编号,否则输出“WRONG”
编号之间用一个空格间隔,最后一个编号后不能有空格
如(n=8,m=5时)上述例子的输出应为:
5 2 8 7 1 4 6 3
*/
//Player1.h
class Player1
{
public:
int num;
bool life;
Player1(int n = 0)
{
num = n;
life = true;
}
void die()
{
life = false;
}
};
//Queue1.h
#include "Player1.h"
#include <iostream>
using namespace std;
class Queue1
{
public:
int len;
Player1 *people;
Queue1(int n = 1)
{
len = n;
people = new Player1 [n+1];
for(int i = 0;i<n;i++)
people[i].num = i + 1;
}
void Play(int m)
{
int dead = 0;
int playnum = 0;
for(int i = 0;dead<len;i=(i+1)%len)
{
if(people[i].life == true)
playnum++;
if(playnum==m)
{
people[i].die();
playnum = 0;
dead++;
cout<<people[i].num;
if(dead<len)
cout<<" ";
}
}
cout<<endl;
}
};
//Player2.hclass Player2{public: int num; bool life; Player2* next; Player2(int n = 0) { num = n; life = true; } void die() { life = false; }};
//Queue2.h#include "Player2.h"#include <iostream>using namespace std;class Queue2{private: int len; Player2* head; Player2* curr;public: Queue2(int n = 1) { if(n>=1) { len=n; head=new Player2(1); curr=head; for(int i=2;i<=n;i++) { Player2 *t=new Player2(i); curr->next=t; curr=curr->next; } } curr->next=head; } void Play(int m) { curr=head; int dead=0; int playnum=0; for(;dead<len;curr=curr->next) { if(curr->life==true) { playnum++; } if(playnum==m) { curr->die(); playnum=0; dead++; cout<<curr->num; if(dead<len) { cout<<" "; } } } cout<<endl; } };
#include "Queue1.h"#include "Queue2.h"#include <fstream>using namespace std;int main(){ int n,m; //cin>>n>>m; ifstream infile("input1.txt"); infile>>n>>m; infile.close(); Queue1 a(n); Queue2 b(n); a.Play(m); b.Play(m); return 0;}
delete_all方法对于stack类
/*利用教材中的Stack类,为其设计外部函数(非成员函数)实现下面delete_all功能,必要时可以使用临时的Stack对象编写主函数测试delete_all函数,栈元素设定为字符类型即可template <class T>void delete_all(Stack<T> &s, const T &x)------删除栈s中所有等于x的数据项,保持其他数据项顺序不变。输入:input.txt,其第一个字符为x,其后按栈底到栈顶的顺序依次给出栈中字符,字符间用空格、回车或制表符间隔如:ab a t a a e c表示栈底栈顶内容为b a t a a e c要删除内容为a输出:删除后栈中字符内容,从栈顶到栈底的顺序即可,相邻元素间用空格间隔,最后一个元素之后不能有空格。最后输出一个回车。如上例,应为―――――――――c e t b―――――――――――――注意:应正确处理输入中空栈等情况。*/#include <stack>#include <iostream>#include <fstream>using namespace std;template <class T>void delete_all(stack<T> &s,const T& x){ if(s.empty()) { cout<<"Stack is empty!"<<endl; return; } stack<T> temp; while(!s.empty()) { if(s.top()==x) { s.pop(); } else { temp.push(s.top()); s.pop(); } } while(!temp.empty()) { s.push(temp.top()); temp.pop(); }}int main(){ stack<char> m; char a,t,n; ifstream infile("input.txt"); infile>>a; infile.get(t); while(infile>>n) m.push(n); delete_all<char> (m,a); while(!m.empty()) { cout<<m.top(); m.pop(); if(!m.empty()) cout<<" "; } cout<<endl; return 0;}
作业五
neverUsed化的hashtable类
/*开发一个基于线性探查的散列表类,要求用neverUsed思想进行删除操作其中有一个方法:它在60%的空桶的neverUsed域的值为false时,重新组织散列表重新组织散列表的过程中,要在必要时移动记录重新组织之后,每个空桶的neverUsed域的值为true*/
//标头.h#pragma once#include<iostream>using namespace std;template<typename T>class HashTable {private: int size; T* items; bool * neverused;public: HashTable(int n) { size = n; items = new T[size]; neverused = new bool[size]; for (int k = 0; k < size; k++) { items[k] = 0; neverused[k] = 1; } } HashTable(const HashTable<T>&target) { size = target.size; items = new T[size]; neverused = new bool[size]; for (int k = 0; k < size; k++) { items[k] = target.items[k]; neverused[k] = target.neverused[k]; } } ~HashTable() { delete[]items; delete[]neverused; } void operator =(HashTable<T> target) { delete[]items; delete[]neverused; size = target.size; items = new T[size]; neverused = new bool[size]; for (int k = 0; k < size; k++) { items[k] = target.items[k]; neverused[k] = target.neverused[k]; } } int hash(const T &t) { return t%10; } int search(const T &t) { int i = hash(t) % size; int j = 0; while (1) { if (neverused[(i + j) % size] == 1 || items[(i + j) % size] == t) return (i + j)%size; j++; if (((i + j) % size) == i) break; } return ((i + j) % size); } bool find(const T&t) { int n = search(t); if (neverused[n] == 1 || items[n] != t)return false; return true; } bool needReset() { int n = 0; for (int k = 0; k < size; k++) { if (neverused[k] == 0)n++; } if (double(n) / double(size) >= 0.6)return true; return false; } void insert(T t) { int n = search(t); if (neverused[n] == 1) { neverused[n] = 0; items[n] = t; } } void erase(T t) { int n = search(t); if (neverused[n] == 1 || items[n] != t)cout << "该元素不存在" << endl; else items[n] = 0; if (needReset())reset(); } void output() { cout << "输出哈希表" << endl; for (int k = 0; k < size; k++) cout << items[k] << " "; cout << endl; for (int k = 0; k < size; k++) cout << neverused[k] << " "; cout << endl; } void reset() { HashTable<T> temp(size); for (int k = 0; k < size; k++) { if (items[k] != 0) { temp.insert(items[k]); } } *this = temp; }};
#include "标头.h"int main() { int n; cin >> n; cout << n << endl; HashTable<int> table(n); table.output(); int *temp = new int [n]; for(int i=0;i<n;i++) { cin>>temp[i]; table.insert(temp[i]); } table.output(); int t = 0; cout << "请输入要删除的数" << endl; cin >> t; table.erase(t); table.output(); cout << "请输入要添加的数" << endl; cin >> t; table.insert(t); cout << "请输入要添加的数" << endl; cin >> t; table.insert(t); cout << "请输入要添加的数" << endl; cin >> t; table.insert(t); table.output(); cout << "请输入要删除的数" << endl; cin >> t; table.erase(t); table.output(); cout << "请输入要删除的数" << endl; cin >> t; table.erase(t); table.output(); system("pause"); return 0;}
hashChainwithTail
/*设计一个类hashChainswithTail其中每个散列链表都是一个有尾节点的有序链表而且所有链表在物理上都共享一个尾节点PS.不使用任何链表类的方法实现插入与删除*/
//标头.h#pragma once#include<iostream>using namespace std;template<typename T>class Node {public: T item; Node<T>*next; Node(T t = 0, Node<T>*temp = NULL) { item = t; next = temp; }};template<typename T>class Chain {private: Node<T>*tail; Node<T>*head;public: Chain(Node<T>*temp = NULL) { head = tail = temp; } ~Chain() { Node<T>*temp = head; while (temp != tail) { head = head->next; delete temp; temp = head; } } bool isempty() { if (head == tail)return true; return false; } void insert(T t) { if (head == NULL) { head = new Node<T>(t,tail); return; } Node<T>*temp = new Node<T>(t); Node<T>*curr = head; while (curr != NULL) { if ((curr->item<t) && (curr->next->item>t)) { temp->next = curr->next; curr->next = temp; return; } curr = curr->next; } } void erase(T t) { if (head == NULL) { cout << "该元素不存在" << endl; return; } if (head->item == t) { Node<T>*temp = head; head = head->next; delete temp; return; } int i = tail->item; tail->item = t; Node<T>*curr = head->next; while (1) { if (curr->next->item == t) break; curr = curr->next; } if (curr->next == tail) { cout << "该元素不存在" << endl; return; } Node<T>*temp = curr->next; curr->next = curr->next->next; delete temp; tail->item = i; return; } void output() { Node<T>*curr = head; if (head == NULL) { cout <<"NULL"<< endl; return; } while (curr != tail) { cout << curr->item << " "; curr = curr->next; } cout << endl; } template<typename T> friend class HashChain;};template<typename T>class HashChain {private: int size; Chain<T> *chain; T Max; Node<T> *theOnlyTail;public: HashChain(int n = 11, int m = 100) { size = n; Max = m; theOnlyTail = new Node<T>(Max); chain = new Chain<T>[size]; for (int k = 0; k < size; k++) chain[k].tail = theOnlyTail; } int hash(const T &t) { return 3 * int(t) + 7; } int search(const T &t) { int i = hash(t) % size; return i; } void insert(T t) { int i = search(t); chain[i].insert(t); } void erase(T t) { int i = search(t); chain[i].erase(t); } void output() { cout <<"输出哈希散列" << endl; for (int k = 0; k < size; k++) chain[k].output(); }};
#include"标头.h"#include<fstream>int main() { ifstream fin("input.txt"); int n = 0; while (fin.peek() >= '0'&&fin.peek() <= '9') n = n * 10 + fin.get() - '0'; cout <<"size:"<< n << endl; fin.get(); int max = 0; while (fin.peek() >= '0'&&fin.peek() <= '9') max = max * 10 + fin.get() - '0'; cout << "max:" << max << endl; fin.get(); HashChain<int> c(n,max); while (1) { int m = 0; while (fin.peek() >= '0'&&fin.peek() <= '9') m = m * 10 + fin.get() - '0'; if (m != 0)c.insert(m); char ch = fin.get(); if (ch == '\n')break; } c.output(); int t = 0; cout << "请输入要删除的元素" << endl; cin >> t; c.erase(t); c.output(); cout << "请输入要删除的元素" << endl; cin >> t; c.erase(t); c.output(); system("pause"); return 0;}
作业六
deque双端队列
/*双端队列(double-ended queue,deque),就是在列表的两端都可以插入和删除数据它允许的操作有Create、IsEmpty、IsFull、Left、Right、AddLeft、AddRight、DeleteLeft、DeleteRight使用循环数组方式实现双端队列,要求实现上述操作,并实现一个Print输出操作能将队列由左至右的次序输出于一行,元素间用空格间隔,队列元素类型设为整型输入:input.txt,给出一个操作序列,可能是Create、Print之外的任何操作,需要的情况下,会给出参数。最后以关键字“End”结束例如:AddLeft 1AddLeft 2DeleteRightIsFullDeleteLeftIsEmptyAddRight 3AddLeft 2AddRight 1End输出:程序开始执行时,队列设置为空按输入顺序执行操作,每个操作执行完后,将结果输出于一行对于错误命令,输出“WRONG”对IsEmpty和IsFull命令,试情况输出“Yes”或“No”对Left和Right命令,若队列空,输出“EMPTY”,否则输出对应队列元素对Add命令,若队列满,输出“FULL”,否则调用Print,输出队列所有元素对Del命令,若队列空,输出“EMPTY”,否则输出所有元素元素间用空格间隔,最后一个元素后不能有空格。最后输出一个回车例如,对上例,应输出:―――――――――12 12NoYes32 32 3 1――――――――――――――――*/#include <bits/stdc++.h>using namespace std;string cmd[10] = {"End","AddLeft","AddRight","DeleteLeft","DeleteRight","IsFull","IsEmpty","Left","Right"};int which_cmd(string s){ int temp = -1; int i; for(i=0;i<=8;i++) { if(cmd[i]==s) { temp = i; } } return temp; } template <class T>struct Node{ T data; Node<T>* left; Node<T>* right; Node() { left = NULL; right = NULL; } Node(T d) { data = d; left = NULL; right = NULL; } };template <class T>struct Deque{private: int MaxLength; int Length; Node<T>* L; Node<T>* R;public: Deque(int s = 5) { MaxLength = s; Length = 0; L = new Node<T>(); R = new Node<T>(); } bool IsEmpty() { return Length==0; } bool IsFull() { return Length==MaxLength; } void LeftPrint() { if(IsEmpty()) { cout<<"EMPTY"<<endl; return; } Node<T>* Z = L; for(int i=1;i<Length;i++) { cout<<Z->data<<" "; Z = Z->right; } cout<<R->data<<endl; } void RightPrint() { if(IsEmpty()) { cout<<"EMPTY"<<endl; return; } Node<T>* Z = R; for(int i=1;i<Length;i++) { cout<<Z->data<<" "; Z = Z->left; } cout<<L->data<<endl; } void AddLeft(T data) { Node<T>* temp = new Node<T>(data); if(IsFull()) { cout<<"FULL"<<endl; return; } if(IsEmpty()) { L = temp; R = temp; Length++; LeftPrint(); return; } L->left = temp; temp->right = L; L = temp; Length++; LeftPrint(); } void AddRight(T data) { Node<T>* temp = new Node<T>(data); if(IsFull()) { cout<<"FULL"<<endl; return; } if(IsEmpty()) { L = temp; R = temp; Length++; LeftPrint(); return; } R->right = temp; temp->left = R; R = temp; Length++; LeftPrint(); } bool DeleteLeft() { if(IsEmpty()) { return false; } if(Length==1) { Length = 0; cout<<"Empty"<<endl; return true; } Node<T>* temp = L->right; temp->left = NULL; L = temp; Length--; LeftPrint(); return true; } bool DeleteRight() { if(IsEmpty()) { return false; } if(Length==1) { Length = 0; cout<<"Empty"<<endl; return true; } Node<T>* temp = R->left; temp->right = NULL; R = temp; Length--; LeftPrint(); return true; }};int main(){ Deque<int> dq; string s; int temp; while(cin>>s) { int flag = which_cmd(s); switch(flag) { case 0: return 0; case -1: cout<<"WRONG"<<endl; break; case 1: cin>>temp; dq.AddLeft(temp); break; case 2: cin>>temp; dq.AddRight(temp); break; case 3: if(dq.DeleteLeft()==false) { cout<<"EMPTY"<<endl; } break; case 4: if(dq.DeleteRight()==false) cout<<"EMPTY"<<endl; break; case 5: if(dq.IsFull()) { cout<<"YES"<<endl; } else { cout<<"NO"<<endl; } break; case 6: if(dq.IsEmpty()) { cout<<"YES"<<endl; } else { cout<<"NO"<<endl; } break; case 7: dq.LeftPrint(); break; case 8: dq.RightPrint(); break; } } return 0;}
中缀表达式左根输出
/*输入一个中缀表达式(infix notation),构造表达式的二叉树(Binary tree),以文本方式输出树结构以缩进表示二叉树(Binary tree)的层次左——根、右——叶、上——右子树、下——左子树示例:输入:a+b+c*(d+e)输出:――――――――――――――――――― e + d * c+ b + a――――――――――――――――――――――ps:以什么样的顺序对树进行遍历可以容易地输出为这种形式?标准顺序显然是不行的。不同层次对应不同缩进如何实现?可以为递归函数设定一个参数表示层次(缩进量),递归调用时加以改变即可。另外,如何将input.txt转换为二叉树结构,除了链接实现的二叉树结构外,可能还需要一些辅助结构。*/#include <bits/stdc++.h>using namespace std;int GetLength(string s){ int len = 0; while (s[len] != '\0') { len++; } return len;}string midtobeh(string s){ string temp = ""; map<char, int> op; stack<char> stk; op['('] = 0; op[')'] = 0; op['+'] = 1; op['-'] = 1; op['*'] = 2; op['/'] = 2; for (int i = 0; i < GetLength(s); i++) { if (op.count(s[i])) { if (s[i] == ')') { while (stk.top() != '(') { temp += stk.top(); stk.pop(); } stk.pop(); } else if (stk.empty() || s[i] == '(' || op[s[i]] > op[stk.top()]) { stk.push(s[i]); } else if (op[s[i]] <= op[stk.top()]) { while (op[s[i]] <= op[stk.top()] && (!stk.empty())) { temp += stk.top(); stk.pop(); if (stk.empty()) break; } stk.push(s[i]); } } else { temp += s[i]; } /* cout<<temp<<"\t"; stk1 = stk; while(!stk1.empty()) { cout<<stk1.top(); stk1.pop(); } cout<<endl; */ if (i == GetLength(s) - 1) { while (!stk.empty()) { temp += stk.top(); stk.pop(); } break; } } return temp;}struct Node{ char c; Node* left; Node* right; Node(char ch = 0) { c = ch; left = NULL; right = NULL; }};Node *buildtree(string s){ stack<Node *> stk; Node *n,*n1,*n2; for(int i=0;i<GetLength(s);i++) { if((s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z')) { n = new Node(s[i]); stk.push(n); } else { n = new Node(s[i]); n1 = stk.top(); stk.pop(); n2 = stk.top(); stk.pop(); n->left = n2; n->right = n1; stk.push(n); } } n = stk.top(); stk.pop(); return n;}void visit(Node* temproot, int level);void output(Node* root){ Node* temp = root; int level = 0; if(root->right!=NULL) visit(root->right, ++level); --level; cout << root->c << endl; if(root->left!=NULL) visit(root->left, ++level); --level;}void visit(Node* temproot, int level) { if (temproot->right != NULL) { visit(temproot->right, ++level); --level; } for (int k = 0; k < 2 * level; k++) cout << ' '; cout << temproot->c << endl; if (temproot->left != NULL) { visit(temproot->left, ++level); --level; }}int main(){ string s,data; cin >> s; data = midtobeh(s); Node* n = buildtree(data); output(n); return 0;}
BinaryTree类的成员函数
/*编写二叉树类(Binary tree)的成员函数,分别实现以下功能:1.统计二叉树的叶节点的数目2.交换二叉树中所有节点的左右子树3.按层次顺序遍历二叉树:首先访问根节点,然后是它的两个孩子节点,然后是孙子节点,依此类推4.求二叉树的宽度,即同一层次上最多的节点数要求:以任意可行的方式输入一棵二叉树,程序依次显示上述各项处理的结果*/#include <bits/stdc++.h>using namespace std;int num = 1,width;struct Node { int data; Node *left; Node *right; Node() { left = right = NULL; } Node(const int& x) { data = x; left = NULL; right = NULL; }};class BinTree {public: Node *root; BinTree() { root = NULL; } void CreatRoot(const int& x) { if(root) root->data = x; else root = new Node(x); } bool InsertLeftChild(Node *node, const int& x) { if(node==NULL) return false; Node* newNode = new Node(x); node->left = newNode; return true; } bool InsertRightChild(Node *node, const int& x) { if(node==NULL) return false; Node* newNode = new Node(x); node->right = newNode; return true; } Node* GetLeftChild(Node* node) { if(!node) return NULL; return node->left; } Node* GetRightChild(Node* node) { if(!node) return NULL; return node->left; } void ChangeLR(Node* node) { if((node->left==NULL)&&(node->right==NULL)) return; if(node->left==NULL) { node->left = node->right; node->right = NULL; return; } if(node->right==NULL) { node->right = node->left; node->left = NULL; return; } Node* newNode = node->left; node->left = node->right; node->right = newNode; ChangeLR(node->left); ChangeLR(node->right); } void GetNumber(Node* node) { if(node == NULL) return; if(node->left!=NULL&&node->right!=NULL) num++; GetNumber(node->left); GetNumber(node->right); } void CengCiBianLi(Node* node) { if(node == NULL) width = 0; int max = -1; deque<Node*> c; Node* last = root; c.push_back(node); while(!c.empty()) { Node* temp = c.front(); width++; if(temp) { cout<<temp->data<<" "; c.pop_front(); if(temp->left) { c.push_back(temp->left); } if(temp->right) { c.push_back(temp->right); } if(temp == last) { if(!c.empty()) { last = c.back(); } if(width>=max) { max = width; width = 0; } } } else { c.pop_front(); } } width = max; } void PreOrderTraverse(Node* node); void InOrderTraverse(Node* node); void PostOrderTraverse(Node* node);};void BinTree::PreOrderTraverse(Node* node) { if(node == NULL) return; cout << node->data << ' '; PreOrderTraverse(node->left); PreOrderTraverse(node->right);}void BinTree::InOrderTraverse(Node* node) { if(node == NULL) return; InOrderTraverse(node->left); cout << node->data << ' '; InOrderTraverse(node->right);}void BinTree::PostOrderTraverse(Node* node) { if(node == NULL) return; PostOrderTraverse(node->left); PostOrderTraverse(node->right); cout << node->data << ' ';}int main(){ BinTree tree; tree.CreatRoot(1); /* tree.InsertLeftChild(tree.root,2); tree.InsertRightChild(tree.root,3); tree.InsertLeftChild(tree.root->left,4); tree.InsertRightChild(tree.root->left,5); tree.InsertRightChild(tree.root->right,6); */ tree.InsertLeftChild(tree.root,2); tree.InsertLeftChild(tree.root->left,3); tree.InsertLeftChild(tree.root->left->left,4); tree.PreOrderTraverse(tree.root); tree.GetNumber(tree.root); cout<<endl<<num<<endl; tree.ChangeLR(tree.root); tree.PreOrderTraverse(tree.root); cout<<endl; tree.CengCiBianLi(tree.root); cout<<endl<<width<<endl; return 0;}