数据结构实验一:线性表,堆栈和队列实现
数据结构实验二 :二叉树的操作与实现
数据结构实验三: 图的操作与实现
数据结构实验四 : 查找和排序算法实现
文章目录
一、实验目的:
1、 领会单链表存储结构和掌握单链表中的各种基本运算算法设计;
2、 领会栈链存储结构和掌握栈链中的各种基本运算算法设计;
3、 领会环形队列存储结构和掌握环形队列中的各种基本运算算法设计;
4、 深入掌握单链表应用的算法设计;
5、 掌握栈应用的算法设计;
二、使用仪器、器材
微机一台
操作系统:WinXP
编程软件:C/C++编程软件
三、实验内容及原理
1、教材 P74 实验题 2:实现单链表的各种基本运算的算法
编写一个程序 linklist.cpp,实现单链表中的各种基本运算和整体建表算
法(假设单链表的元素类型 ElemType 为 char),并在此基础上设计一个程序
exp2-2.cpp 完成以下功能。
(1)初始化单链表 h。
(2)依次采用尾插法插入 a、b、c、d、e 元素。
(3)输出单链表 h。
(4)输出单链表 h 的长度。
(5)判断单链表 h 是否为空。
(6)输出单链表 h 的第 3 个元素。
(7)输出元素 a 的位置。
(8)在第 4 个元素位置上插入 f 元素。
(9)输出单链表 h。
(10)删除单链表 h 的第 3 个元素。
(11)输出单链表 h。
(12)释放单链表 h。
#include<iostream>
using namespace std;
class linklist
{
char data;
linklist* tail;
public:
linklist() ;
~linklist();
int init();//初始化
int push(char x);//尾插入
void showList();//遍历输出单链表
int showLength();//展示长度
int empty();//是否为空
char showNode(int n);//输出第n个元素的
int showLocation(char x);//第n个元素的位置
int insert(int n,char f);//第n个位置插入f
int Delete(int n);//删除第n个元素
int Rlease();//释放所有元素;
private:
};
/**
*1)初始化单链表h。
(2)依次采用尾插法插入a、b、c、d、e元素。
(3)输出单链表h。
(4)输出单链表h的长度。
(5)判断单链表h是否为空。
(6)输出单链表h的第3个元素。
(7)输出元素a的位置。
(8)在第4个元素位置上插入f元素。
(9)输出单链表h。
(10)删除单链表h的第3个元素。
(11)输出单链表h。
(12)释放单链表h
*
*
*
*/
linklist::linklist()
{
this->tail = NULL;
this->data = NULL;
}
linklist::~linklist()
{
}
//初始化
int linklist::init() {
this->tail = NULL;
return 1;
}//初始化
int linklist::push(char x) {//依次采用尾插法插入a、b、c、d、e元素
linklist* temp = this;
while (temp->tail)
{
temp=temp->tail;
}
linklist* newNode = new linklist();
newNode->data = x;
newNode->tail = NULL;
temp->tail = newNode;
return 1;
}
void linklist::showList() {//遍历输出单链表
linklist* temp = this;//头节点
while (temp->tail) {//直到空
temp = temp->tail;
cout << temp->data << endl;
}
}
int linklist::showLength() {
if (empty()) {
return 0;
}
int length=0;
linklist* temp = this;
while (temp->tail) {
temp = temp->tail;
length++;
}
return length;
}//展示长度
int linklist::empty() {
linklist* temp = this;
if (temp->tail) {
return 0;//非空
}else {
return 1;//空
}
}//是否为空
char linklist::showNode(int n){//输出第n个元素的
if (empty()) {
return 0;
}
int length = 0;
linklist* temp = this;
while (temp->tail) {
temp=temp->tail;
length++;
if (length == n) {
break;
}
}
return temp->data;
}
int linklist::showLocation(char x) {//元素x的位置(从1开始)
linklist* temp = this;
int length = 0;
if (empty()) {//
return 0;
}
while (temp->tail) {
temp = temp->tail;
length++;
if (temp->data == x) {
return length;
}
}
return 0;
}
/// //
int linklist::insert(int n, char f){//第n个位置插入f
linklist* temp = this;
linklist* pre = this;
int length = 0;
while (length != n) {
if (temp->tail) {//不为空
pre = temp;
temp = temp->tail;//往下
length++;
}else{
pre = temp;
linklist* newNode = new linklist();//新建节点
newNode->data = NULL;
newNode->tail = NULL;
temp->tail = newNode;
temp = temp->tail;
length++;
}
}
if (temp->data == NULL) {
temp->data = f;
}else {
linklist* node = new linklist();
node->data = f;//赋值
node->tail = temp;//新节点指向下一个节点
pre->tail = node;//前节点指向新节点
}
return 1;
}
int linklist::Delete(int n) {//删除第n个元素
linklist* temp = this;
linklist* pre = this;
int length = 0;
while (length != n) {//
if (temp->tail) {//非空
pre = temp;
temp = temp->tail;
length++;
}else {//还没到n就没了节点
return 0;
}
}
pre->tail = temp->tail;
delete temp;//删除节点
return 1;
}
int linklist::Rlease() {
//释放空间
linklist* temp = this;
while (temp->tail) {
linklist* Dnote = temp->tail;
temp->tail = temp->tail->tail;
delete Dnote;
}
return 1;
}
int main() {
linklist* arr = NULL;
char order = NULL;
int number = NULL;
char temp = NULL;
cout << "0:退出" <<endl;
cout << "A:初始化单链表h" << endl;
cout << "B:依次采用尾插法插入元素" << endl;
cout << "C:输出单链表h" << endl;
cout << "D:输出单链表h的长度" << endl;
cout << "E:判断单链表h是否为空" << endl;
cout << "F:输出单链表h的第n个元素" << endl;
cout << "G:输出元素a的位置" << endl;
cout << "H:在第n个元素位置上插入f元素" << endl;
cout << "I:删除单链表h的第n个元素" << endl;
cout << "J:释放单链表h" << endl;
cin >> order;
while (order!='0') {
switch (order)
{
case 'A':
//如果不为空//则提示删除
if (arr != NULL) {
cout << "链表不为空" << endl;
cout << "输入 :Y 删除旧数据重新初始化" << endl;
cout << "输入 :N 取消初始化操作" << endl;
cin >> temp;
if (temp == 'Y') {
if (arr->Rlease()) {
cout << "删除成功" << endl;
}
else {
cout << "删除失败" << endl;
}
break;
}
cout << "取消成功"<<endl;
break;
}
else {
arr = new linklist();
if (arr->init()) {
cout << "初始化成功"<<endl;
}
break;
}
//空则建立
case 'B':
cout << "请输入数据元素" << endl;
cout << "输入 '0'停止添加元素"<<endl;
cin >> temp;
while (temp!='0') {
if (arr->push(temp)) {
cout << "插入成功" << endl;
}
cin >> temp;
}
cout << "添加结束"<<endl;
break;
case 'C':
cout << "链表输出为:" << endl;
arr->showList();
break;
case 'D':
cout << "链表长度:" << endl;
cout<<arr->showLength()<<endl;
break;
case 'E':
if (arr->empty()) {
cout << "空" << endl;
}
else {
cout << "非空" << endl;
}
break;
case 'F':
cout << "请输入元素的位置数:";
cin >> number;
cout << number<<endl;
if (arr->showNode(number)) {
cout << "第" << number << "元素为:" << arr->showNode(number)<<endl;
}
else {
cout << "链表为空或没有该数" << endl;
}
break;
case 'G':
cout << "请输入元素值:" << endl;
cin >> temp;
if (arr->showLocation(temp)) {
cout << "元素:" << temp << "位置为:" << arr->showLocation(temp) << endl;
}else{
cout << "链表为空或没有该数" << endl;
}
break;
case 'H':
cout << "输入位置 n" << endl;
cout << "n =";
cin >> number;
cout << "输入元素值 f" << endl;
cout << "f =";
cin >> temp;
if (arr->insert(number, temp)) {
cout << "插入成功" << endl;
}
else {
cout << "插入失败";
}
break;
case 'I':
cout << "输入删除位置 n" << endl;
cout << "n =";
cin >> number;
if (arr->Delete(number)) {
cout << "删除成功" << endl;
}
else {
cout << "删除失败";
}
break;
case 'J':
if (arr->Rlease()) {
cout << "释放成功"<<endl;
}
else {
cout << "释放失败" << endl;
}
break;
default:
break;
}
cout << "请输入操作指令:" << endl;
cin >> order;
}
return 0;
}
2、教材 P118 实验题 2:实现链栈的各种基本运算的算法
编写一个程序 linkstack.cpp,实现链栈(假设栈中元素类型 ElemType 为
char)的各种基本运算,并在此基础上设计一个程序 exp3-2.cpp 完成以下功能。
(1)初始化栈 s。
(2)判断栈 s 是否为空。
(3)依次进栈元素 a、b、c、d、e。4
(4)判断栈 s 是否非空。
(5)输出出栈序列。
(6)判断栈 s 是否非空。
(7)释放栈。
#include<iostream>
using namespace std;
template<class Type>
class stackANT {//抽象类方法
public:
virtual int initStack() = 0;//初始化
virtual bool isEmpty()const = 0;//空
virtual bool isFullStack()const = 0;//满
virtual int push(const Type&) = 0;//入栈
virtual int pop()= 0;//出栈
virtual Type top()const = 0;//返回栈顶
virtual void showList()const=0;//展示栈
virtual int Relase()=0;//释放栈
};
template<class Type>
struct node {
Type info;
node<Type>* next;
};
template<class Type>
class linkStack:public stackANT<Type> {
public:
linkStack();
linkStack(const linkStack<Type>&);
//const linkStack<Type>& operator=(const linkStack<Type>&);
~linkStack();
int initStack();//初始化
bool isEmpty()const;//空
bool isFullStack()const;//满
int push(const Type&);//插入
int pop();//出
Type top()const;//返回顶
void showList()const;
int Relase();
private:
node<Type>* stackTop;
};
template<class Type>
linkStack<Type>::linkStack() {
initStack();//没有this都可以指向吗
}
template<class Type>
linkStack<Type>::~linkStack() {
initStack();
}
template<class Type>
int linkStack<Type>::initStack() {//初始化
try {
while (stackTop) {//头往下走,边走边删,释放所有节点内存
node<Type>* temp = stackTop;
stackTop = stackTop->next;
delete temp;
}
return 1;
} catch (const std::exception&) {
return 0;
}
}
template<class Type>
bool linkStack<Type>::isEmpty()const {//空
return stackTop == nullptr;
}
template<class Type>
bool linkStack<Type>::isFullStack()const {//满
return 0;//基本不可能会满
}
template<class Type>
int linkStack<Type>::push(const Type& info) {//入栈
try {
node<Type>* newNode = new node<Type>;
newNode->info = info;
newNode->next = stackTop;//入栈
stackTop = newNode;
return 1;
} catch (const std::exception&) {
return 0;
}
}
template<class Type>
int linkStack<Type>::pop() {
try {
if (isEmpty()) {
return 0;
} else {
node<Type>* temp;//出栈
temp = stackTop;//记录当前点
stackTop = stackTop->next;//头节点作为栈顶
delete temp;//删除节点
return 1;
}
} catch (const std::exception&) {
return 0;
}
}
template<class Type>
Type linkStack<Type>::top()const {
try {
if (!isEmpty()) {
return stackTop->info;
}//非空
} catch (const std::exception&) {
cout << "数据错误";
}
}
template<class Type>
void linkStack<Type>::showList()const {
if (isEmpty()) {
return;
} else {
node<Type>* temp = stackTop;
do {
cout << temp->info << endl;//遍历
temp = temp->next;
} while (temp);
}
}
template<class Type>
int linkStack<Type>::Relase() {
return initStack();
}
int main() {
linkStack<char>* Stack = new linkStack<char>();
char order = NULL;
char temp = NULL;
cout << "0:退出" << endl;
cout << "A:初始化栈" << endl;
cout << "B:入栈" << endl;
cout << "C:输出出栈序列" << endl;
cout << "D:判断栈是否为空" << endl;
cout << "E:释放单链表h" << endl;
cin >> order;
while (order != '0') {
switch (order) {
case 'A':
if (Stack->initStack()) {
cout << "初始化成功"<<endl;
} else {
cout << "初始化失败"<<endl;
}
break;
case 'B':
while (true) {
cout << "请输入入栈元素:" << endl;
cin >> temp;
if (temp=='0') {
cout << "停止入栈" << endl;
break;
}
if (Stack->push(temp)) {
cout << "入栈成功" << endl;
} else {
cout << "入栈失败" << endl;
}
}
break;
case 'C':
cout << "输出出栈序列:" << endl;
Stack->showList();
break;
case 'D':
cout << "栈为:" << endl;
if (Stack->isEmpty()) {
cout << "空" << endl;
} else {
cout << "非空" << endl;
}
break;
case 'E':
if (Stack->Relase()) {
cout << "释放成功" << endl;
} else {
cout << "释放失败" << endl;
}
default:
break;
}
cout << "请输入操作指令:" << endl;
cin >> order;
}
return 0;
}
3、教材 P118 实验题 3:实现链队各种基本运算的算法
编写一个程序 liqueue.cpp,实现链队(假设队列中元素类型 ElemType 为
char)的各种基本运算,并在此基础上设计一个程序 exp3-3.cpp 完成以下功能。
(1)初始化队列 q。
(2)判断队列 q 是否非空。
(3)依次进队元素 a、b、c。
(4)出队一个元素,输出该元素。
(5)依次进队元素 d、e、f。判断单链表 h 是否为空。
(6)输出出队序列。
(12)释放队列。
#include<iostream>
using namespace std;
template<class Type>
struct node {
Type data;
};
template<class Type>
class Queen {
public:
Queen();
~Queen();
//初始化队列q。
//(2)判断队列q是否非空。
//(3)依次进队元素a、b、c。
//(4)出队一个元素,输出该元素。
//(5)依次进队元素d、e、f。
//(6)输出出队序列。
//(12)释放队列。
int init(int m);
int empty();
int push(Type& info);
int pop();
int isFull();
void showList();
int Release();
private:
node<Type>* queen;
int length;
int front;
int tail;
};
template<class Type>
Queen<Type>::Queen() {
queen=NULL;
front=NULL;
tail=NULL;
length = NULL;
}
template<class Type>
Queen<Type>::~Queen() {
}
template<class Type>
int Queen<Type>::init(int m) {//初始化
if (!empty()) {
Release();
}
this->queen = new node<Type>[m];
this->front = 0;
this->tail = 0;
this->length = m;
return 1;
}
template<class Type>
int Queen<Type>::empty() {//判断队列q是否非空。
return front == tail;
}
template<class Type>
int Queen<Type>::isFull() {//判断队列q是否非空。
return (tail+1)%length==front;//取模循环
}
template<class Type>
int Queen<Type>::push(Type &info) {//出队
if (isFull()) return 0;
this->queen[tail].data = info;
tail = (tail + 1) % length;//取模循环
return 1;
}
template<class Type>
int Queen<Type>::pop() {//出队
if (empty()) {
return 0;
}
Type temp = queen[front].data;//取模
front = (front + 1) % length;
return temp;
}
template<class Type>
int Queen<Type>::Release() {
delete queen;
return 1;
}
template<class Type>
void Queen<Type>::showList() {
int temp = front;
while (temp != tail) {//遍历
cout << queen[temp].data << endl;
temp = (temp + 1) % length;
}
}
int main() {
Queen<char>* queen = new Queen<char>();
char order = NULL;
char temp = NULL;
int number=NULL;
cout << "0:退出" << endl;
cout << "A:初始化队列" << endl;
cout << "B:入队" << endl;
cout << "C:出队" << endl;
cout << "D:队列是否为空" << endl;
cout << "E:是否满" << endl;
cout << "F:释放单链表h" << endl;
cout << "G:输出出队序列" << endl;
cin >> order;
while (order != '0') {
switch (order) {
case 'A':
cout << "输入循环队列长度 m" << endl;
cin >> number;
if (queen->init(number)) {
cout << "初始化成功";
} else {
cout << "初始化失败";
}
break;
case 'B':
while (true) {
cout << "请输入入栈元素(输入‘0’时退出):" << endl;
cin >> temp;
if (temp == '0') {
break;
} else {
if (queen->push(temp)) {
cout << "成功" << endl;
} else {
cout << "失败" << endl;
}
}
}
break;
case 'C':
if (order=queen->pop()) {
cout << "出队成功" << endl;
cout << "元素值:" << order<<endl;
} else {
cout << "出队失败";
}
break;
case 'D':
cout << "队列" << endl;
if (queen->empty()) {
cout << "空" << endl;
} else {
cout << "不空" << endl;
}
break;
case 'E':
cout << "队列" << endl;
if (queen->isFull()) {
cout << "满" << endl;
} else {
cout << "不满" << endl;
}
break;
case 'F':
if (queen->Release()) {
cout << "释放成功"<<endl;
} else {
cout << "释放失败" << endl;
}
break;
case 'G':
queen->showList();
break;
default:
break;
}
cout << "请输入操作指令:" << endl;
cin >> order;
}
return 0;
}
4、教材 P77 实验题 12:用单链表实现两个大整数的相加运算
编写一个程序 exp2-12.cpp 完成以下功能。
(1)将用户输入的十进制整数字符串转化为带头结点的单链表,每个结点
存放一个整数位。
(2)求两个整数单链表相加的结果单链表。
(3)求结果单链表的中间位,如 123 的中间位为 2,1234 的中间位为 2。
#include<iostream>
#include<vector>
using namespace std;
struct node {
int data;
node* next;
node* pre;
node(int data) {
this->data = data;
this->next = NULL;
this->pre = NULL;
}
};
class Link {
public:
Link();
~Link();
int init(string L);
int addNode(int a);
Link* addList(Link*);
void showList();
int showMidum();
private:
node* head;
node* tail;
int length;
};
Link::Link() {
Link* temp = this;
temp->head = new node(NULL);//初始化一个头节点
temp->tail = temp->head;//头尾指针指向头
temp->length = 1;
}
int Link::init(string L) {
Link* temp = this;
for (int i = L.size() - 1; i >= 0; i--) {
temp->addNode(L[i] - '0');//获取每一个字符转化为数字
//从最后一个开始插入链表便于进位操作
}
temp->length = L.size() + 1;//加上头节点
return 1;
}
int Link::addNode(int a) {
Link* temp = this;//链表中间插入
node* newNode = new node(a);
node* pre = temp->tail;//接尾
temp->tail->next = newNode;
temp->tail = temp->tail->next;
temp->tail->pre = pre;//接头
return 1;
}
Link* Link::addList(Link*s2) {
Link* temp1 = this;
Link* temp2 = s2;
Link* temp3 = new Link();
temp1->tail = temp1->head->next;//第一位
temp2->tail = temp2->head->next;//第一位
//temp3->tail = temp3->head;
int count = 0;//进位数
while (temp1->tail || temp2->tail) {
int n1 = (temp1->tail ? temp1->tail->data : 0);//如果当前值不空则取值,否则取0
int n2 = (temp2->tail ? temp2->tail->data : 0);
int sum = n1 + n2 + count;//每个字符数相加
temp3->addNode(sum % 10);//取个位加入链表
temp3->length++;//链长++
count = sum / 10;//取进位
if (temp1->tail) {//如果当前不空 则后移
temp1->tail = temp1->tail->next;
}
if (temp2->tail) {//如果当前不空则后移
temp2->tail = temp2->tail->next;
}
}
if (count > 0) {//如果有进位则尾加一位
temp3->addNode(count);
}
return temp3;
}
void Link::showList() {
node* temp = this->tail;
while (temp!=this->head) {//遍历输出数字
cout << temp->data;
temp = temp->pre;
}
cout << endl;
}
int Link::showMidum() {
Link* temp = this;//从后往前取中点,因为初始化链表从字符串最后一个开始插入链表
int mid = temp->length/2;//取中点
node* ans = temp->tail;
for (int i = 1; i < mid; i++) {
ans = ans->pre;//找到该点
}
return ans->data;
}
Link::~Link() {
}
int main() {
string a;
string b;
cout << "输入a" << endl;
cin >> a;
Link* l1 = new Link();
l1->init(a);
cout << "输入b" << endl;
cin >> b;
Link* l2 = new Link();
l2->init(b);
Link* l3 = NULL;
l3 = l1->addList(l2);
cout << endl;
cout << "a+b的值:"<<endl;
l3->showList();
cout << "中点:" << endl;
cout << l3->showMidum();
return 0;
}
5、教材 P119 实验题 7:求解栈元素排序问题
编写一个程序 exp3-7.cpp,按升序对一个字符栈进行排序,即最小元素位
于栈顶,最多只能使用一个额外的栈存放临时数据,并输出栈排序过程。
#include<iostream>
#include<stack>
using namespace std;
void showList(stack<int> s1) {
while (!s1.empty()) {
cout << s1.top() << " ";
s1.pop();
}
cout << endl;
}
stack<int> Setorder(stack<int> s1) {
stack<int> temp = stack<int>();
int cur = 0;//暂存值
//s1不空时
while (!s1.empty()) {
//取s1的栈顶暂存
cur = s1.top();
cout << "临时存储" << cur << endl;
s1.pop();
//当s2不空并且 s2栈顶<暂存值 循环入栈s1
while (!temp.empty() && temp.top() < cur) {
s1.push(temp.top());
temp.pop();
cout << "栈1:";
showList(s1);
cout << "临时栈:";
showList(temp);
}
//暂存值入栈s2
temp.push(cur);
}
showList(temp);
return temp;
}
int main() {
stack<int> a;
cout << "栈1:" << endl;
cout << "0:退出" << endl;
cout << "A:入栈" << endl;
cout << "B:排序" << endl;
char order = NULL;
char temp = NULL;
int number=0;
int input = 0;
cin >> order;
while (order != '0') {
switch (order) {
case 'A':
cout << "入栈数:" << endl;
cin >> number;
for (int i = 0; i < number; i++) {
cout << "输入值:";
cin >> input;
a.push(input);
}
break;
case 'B':
cout << "排序" << endl;
Setorder(a);
break;
default:
break;
}
cout << "请输入操作指令:" << endl;
cin >> order;
}
}