某末流學校計算機學院和網絡空間安全學院數據結構作業
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;}