mirror of
https://github.com/cuntoushifu/408.git
synced 2026-11-01 21:33:57 +08:00
严版教材PPT&课后答案
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
- [`DataStructure`**(数据结构)**](数据结构/)
|
||||
- [x] 数据结构1800题
|
||||
- [ ] 数据结构1800题分题目详解
|
||||
- [x] 严版教材PPT&课后习题答案
|
||||
- [x] 严版教材PPT&课后习题答案&书中算法
|
||||
- [x] 王道考研数据结构PPT
|
||||
- [x] 冒泡排序
|
||||
- [x] 王道数据结构思维导图
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
- [x] 数据结构1800题
|
||||
- [ ] 数据结构1800题分题目详解
|
||||
- [x] 王道数据结构课件
|
||||
- [x] 严版教材PPT&课后习题答案
|
||||
- [x] 严版教材PPT&课后习题答案&书中算法
|
||||
- [x] 冒泡排序
|
||||
- [x] 王道数据结构思维导图
|
||||
- [x] 时间复杂度
|
||||
|
||||
BIN
数据结构/严版教材/数据结构实验1必做部分OJ版-配套实验.pdf
Normal file
BIN
数据结构/严版教材/数据结构实验1必做部分OJ版-配套实验.pdf
Normal file
Binary file not shown.
171
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.1-2.5/2.1-2.5.cpp
Normal file
171
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.1-2.5/2.1-2.5.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<string>
|
||||
#include<iomanip>
|
||||
using namespace std;
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。
|
||||
typedef int ElemType; //ElemType 为可定义的数据类型,此设为int类型
|
||||
|
||||
#define MAXSIZE 100 //顺序表可能达到的最大长度
|
||||
struct Book {
|
||||
string id;//ISBN
|
||||
string name;//书名
|
||||
double price;//定价
|
||||
};
|
||||
typedef struct {
|
||||
Book *elem; //存储空间的基地址
|
||||
int length; //当前长度
|
||||
} SqList;
|
||||
|
||||
Status InitList_Sq(SqList &L) { //算法2.1 顺序表的初始化
|
||||
//构造一个空的顺序表L
|
||||
L.elem = new Book[MAXSIZE]; //为顺序表分配一个大小为MAXSIZE的数组空间
|
||||
if (!L.elem)
|
||||
exit(OVERFLOW); //存储分配失败退出
|
||||
L.length = 0; //空表长度为0
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status GetElem(SqList L, int i, Book &e) {//算法2.2 顺序表的取值
|
||||
if (i < 1 || i > L.length)
|
||||
return ERROR; //判断i值是否合理,若不合理,返回ERROR
|
||||
e = L.elem[i - 1]; //elem[i-1]单元存储第i个数据元素
|
||||
return OK;
|
||||
}
|
||||
|
||||
int LocateElem_Sq(SqList L, double e) { //算法2.3 顺序表的查找
|
||||
//顺序表的查找
|
||||
for (int i = 0; i < L.length; i++)
|
||||
if (L.elem[i].price == e)
|
||||
return i + 1;//查找成功,返回序号i+1
|
||||
return 0;//查找失败,返回0
|
||||
}
|
||||
|
||||
Status ListInsert_Sq(SqList &L, int i, Book e) { //算法2.4 顺序表的插入
|
||||
//在顺序表L中第i个位置之前插入新的元素e
|
||||
//i值的合法范围是1<=i<=L.length+1
|
||||
if ((i < 1) || (i > L.length + 1))
|
||||
return ERROR; //i值不合法
|
||||
if (L.length == MAXSIZE)
|
||||
return ERROR; //当前存储空间已满
|
||||
for (int j = L.length - 1; j >= i - 1; j--)
|
||||
L.elem[j + 1] = L.elem[j]; //插入位置及之后的元素后移
|
||||
L.elem[i - 1] = e; //将新元素e放入第i个位置
|
||||
++L.length; //表长增1
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status ListDelete_Sq(SqList &L, int i) { //算法2.5 顺序表的删除
|
||||
//在顺序表L中删除第i个元素,并用e返回其值
|
||||
//i值的合法范围是1<=i<=L.length
|
||||
if ((i < 1) || (i > L.length))
|
||||
return ERROR; //i值不合法
|
||||
for (int j = i; j <= L.length; j++)
|
||||
L.elem[j - 1] = L.elem[j]; //被删除元素之后的元素前移
|
||||
--L.length; //表长减1
|
||||
return OK;
|
||||
}
|
||||
|
||||
int main() {
|
||||
SqList L;
|
||||
int i = 0, temp, a, c, choose;
|
||||
double price;
|
||||
Book e;
|
||||
string head_1, head_2, head_3;
|
||||
cout << "1. 建立\n";
|
||||
cout << "2. 输入\n";
|
||||
cout << "3. 取值\n";
|
||||
cout << "4. 查找\n";
|
||||
cout << "5. 插入\n";
|
||||
cout << "6. 删除\n";
|
||||
cout << "7. 输出\n";
|
||||
cout << "0. 退出\n\n";
|
||||
|
||||
choose = -1;
|
||||
while (choose != 0) {
|
||||
cout << "请选择:";
|
||||
cin >> choose;
|
||||
switch (choose) {
|
||||
case 1://创建顺序表
|
||||
if (InitList_Sq(L))
|
||||
cout << "成功建立顺序表\n\n";
|
||||
else
|
||||
cout << "顺序表建立失败\n\n";
|
||||
break;
|
||||
case 2: {//顺序表信息输入
|
||||
i = 0;
|
||||
L.elem = new Book[MAXSIZE];
|
||||
if (!L.elem)
|
||||
exit(OVERFLOW);
|
||||
L.length = 0;
|
||||
fstream file;
|
||||
file.open("book.txt");
|
||||
if (!file) {
|
||||
cout << "错误!未找到文件!" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
file >> head_1 >> head_2 >> head_3;
|
||||
while (!file.eof()) {
|
||||
file >> L.elem[i].id >> L.elem[i].name >> L.elem[i].price;
|
||||
i++;
|
||||
}
|
||||
cout << "输入 book.txt 信息完毕\n\n";
|
||||
L.length = i;
|
||||
file.close();
|
||||
}
|
||||
break;
|
||||
case 3://顺序表的取值
|
||||
cout << "请输入一个位置用来取值:\n";
|
||||
cin >> i;
|
||||
temp = GetElem(L, i, e);
|
||||
if (temp != 0) {
|
||||
cout << "查找成功\n";
|
||||
cout << "第" << i << "本图书的信息是:\n";
|
||||
cout << left << setw(15) << e.id << "\t" << left << setw(50)
|
||||
<< e.name << "\t" << left << setw(5) << e.price << endl
|
||||
<< endl;
|
||||
} else
|
||||
cout << "查找失败!位置超出范围\n\n";
|
||||
break;
|
||||
case 4: //顺序表的查找
|
||||
cout << "请输入所要查找价格:";
|
||||
cin >> price;
|
||||
temp = LocateElem_Sq(L, price);
|
||||
if (temp != 0) {
|
||||
cout << "查找成功\n";
|
||||
cout << "该价格对应的书名为:" << L.elem[temp - 1].name << endl << endl;
|
||||
} else
|
||||
cout << "查找失败!没有这个价格对应的书籍\n\n";
|
||||
break;
|
||||
case 5: //顺序表的插入
|
||||
cout << "请输入插入的位置和书本信息,包括:编号 书名 价格(用空格隔开):";
|
||||
cin >> a;
|
||||
cin >> e.id >> e.name >> e.price; //输入a和b,a代表插入的位置,b代表插入的数值(书本信息)
|
||||
if (ListInsert_Sq(L, a, e))
|
||||
cout << "插入成功.\n\n";
|
||||
else
|
||||
cout << "插入失败.\n\n";
|
||||
break;
|
||||
case 6: //顺序表的删除
|
||||
cout << "请输入所要删除的书籍的位置:";
|
||||
cin >> c;
|
||||
if (ListDelete_Sq(L, c))
|
||||
cout << "删除成功.\n\n";
|
||||
else
|
||||
cout << "删除失败.\n\n";
|
||||
break;
|
||||
case 7: //顺序表的输出
|
||||
cout << "当前图书系统信息(顺序表)读出:\n";
|
||||
for (i = 0; i < L.length; i++)
|
||||
cout << left << setw(15) << L.elem[i].id << "\t" << left
|
||||
<< setw(50) << L.elem[i].name << "\t" << left
|
||||
<< setw(5) << L.elem[i].price << endl;
|
||||
cout << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
17
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.1-2.5/book.txt
Normal file
17
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.1-2.5/book.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
ISBN 书名 定价
|
||||
9787302257646 程序设计基础 25
|
||||
9787302219972 单片机技术及应用 32
|
||||
9787302203513 编译原理 46
|
||||
9787811234923 汇编语言程序设计教程 21
|
||||
9787512100831 计算机操作系统 17
|
||||
9787302265436 计算机导论实验指导 18
|
||||
9787302180630 实用数据结构 29
|
||||
9787302225065 数据结构(C语言版) 38
|
||||
9787302171676 C#面向对象程序设计 39
|
||||
9787302250692 C语言程序设计 42
|
||||
9787302150664 数据库原理 35
|
||||
9787302260806 Java编程与实践 56
|
||||
9787302252887 Java程序设计与应用教程 39
|
||||
9787302198505 嵌入式操作系统及编程 25
|
||||
9787302169666 软件测试 24
|
||||
9787811231557 Eclipse基础与应用 35
|
||||
189
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.13-2.14/2.13-2.14.cpp
Normal file
189
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.13-2.14/2.13-2.14.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
#include<fstream>
|
||||
#include<iomanip>
|
||||
using namespace std;
|
||||
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。
|
||||
typedef int ElemType; //ElemType 为可定义的数据类型,此设为int类型
|
||||
|
||||
struct Book {
|
||||
string id;//ISBN
|
||||
string name;//书名
|
||||
double price;//定价
|
||||
};
|
||||
typedef struct DuLNode {
|
||||
Book data; //数据域
|
||||
struct DuLNode *prior; //直接前驱
|
||||
struct DuLNode *next; //直接后继
|
||||
} DuLNode, *DuLinkList;
|
||||
|
||||
string head_1, head_2, head_3;
|
||||
int length;
|
||||
|
||||
Status InitDuList_L(DuLinkList &L) {
|
||||
//构造一个空的双向链表L
|
||||
L = new DuLNode; //生成新结点作为头结点,用头指针L指向头结点
|
||||
L->next = NULL; //头结点的指针域置空
|
||||
L->prior = NULL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
DuLNode *GetElemP_DuL(DuLinkList L, int i) {
|
||||
//在带头结点的双向链表L中查找第i个元素,返回结点的地址
|
||||
int j;
|
||||
DuLinkList p;
|
||||
p = L->next;
|
||||
j = 1; //初始化,p指向第一个结点,j为计数器
|
||||
while (j < i && p) { //顺链域向后扫描,直到p指向第i个元素或p为空
|
||||
p = p->next;
|
||||
++j;
|
||||
}
|
||||
if (!p || j > i)
|
||||
return NULL; //第i个元素不存在
|
||||
return p;
|
||||
} //GetElemP_DuL
|
||||
|
||||
Status ListInsert_DuL(DuLinkList &L, int i, Book e) { //算法2.13 双向链表的插入
|
||||
//在带头结点的双向链表L中第i个位置之前插入元素e,i的合法值为1<=i<=表长+1
|
||||
DuLinkList s, p;
|
||||
if (!(p = GetElemP_DuL(L, i))) //在L中确定第i个元素的位置指针p
|
||||
return ERROR; //p为NULL时,第i个元素不存在
|
||||
if (i == 1) {//在双向链表的第一个元素上插入
|
||||
s = new DuLNode; //生成新结点s
|
||||
s->data = e; //将结点s数据置为e
|
||||
DuLinkList p = L->next;
|
||||
L->next = s;
|
||||
s->prior = L;
|
||||
s->next = p;//将结点*s插入L中
|
||||
p->prior = s;
|
||||
++length;
|
||||
} else if (i == length) {//在双向链表的最后一个元素上插入
|
||||
s = new DuLNode; //生成新结点s
|
||||
s->data = e; //将结点s数据置为e
|
||||
DuLinkList p = L;
|
||||
while (p->next)
|
||||
p = p->next;//将LinkList p指向双向链表结尾
|
||||
p->next = s;
|
||||
s->prior = p;//将结点*s插入到p的后面,插入到L中
|
||||
s->next = NULL;
|
||||
++length;
|
||||
} else {
|
||||
s = new DuLNode; //生成新结点*s
|
||||
s->data = e; //将结点*s数据域置为e
|
||||
s->prior = p->prior; //将结点*s插入L中,此步对应图2.20①
|
||||
p->prior->next = s; //对应图2.20②
|
||||
s->next = p; //对应图2.20③
|
||||
p->prior = s; //对应图2.20④
|
||||
++length;
|
||||
}
|
||||
return OK;
|
||||
} //ListInsert_DuL
|
||||
|
||||
Status ListDelete_DuL(DuLinkList &L, int i) { //算法2.14 双向链表的删除
|
||||
//删除带头结点的双向链表L中第i个位置之前插入元素e,i的合法值为1<=i<=表长
|
||||
DuLinkList p;
|
||||
if (!(p = GetElemP_DuL(L, i))) //在L中确定第i个元素的位置指针p
|
||||
return ERROR; //p为NULL时,第i个元素不存在
|
||||
if (i == 1)//删除双向链表的第一个元素
|
||||
L = L->next;
|
||||
else if (i == length) {//删除双向链表的最后一个元素
|
||||
p->prior->next = NULL;
|
||||
delete p;
|
||||
--length;
|
||||
return OK;
|
||||
} else {
|
||||
p->prior->next = p->next; //修改被删结点的前驱结点的后继指针,对应图2.21①
|
||||
p->next->prior = p->prior; //修改被删结点的后继结点的前驱指针,对应图2.21②
|
||||
delete p; //释放被删结点的空间
|
||||
--length;
|
||||
return OK;
|
||||
}
|
||||
}//ListDelete_DuL
|
||||
|
||||
void CreateDuList_L(DuLinkList &L) {
|
||||
//正位序输入n个元素的值,建立带表头结点的双向链表L,同时建立前驱指针
|
||||
DuLinkList r, p;
|
||||
L = new DuLNode;
|
||||
L->next = NULL; //先建立一个带头结点的空链表
|
||||
r = L;//尾指针r指向头结点
|
||||
length = 0;
|
||||
fstream file;
|
||||
file.open("book.txt");
|
||||
if (!file) {
|
||||
cout << "未找到相关文件,无法打开!" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
file >> head_1 >> head_2 >> head_3;
|
||||
while (!file.eof()) {
|
||||
p = new DuLNode; //生成新结点
|
||||
file >> p->data.id >> p->data.name >> p->data.price; //输入元素值
|
||||
p->next = NULL;
|
||||
r->next = p; //插入到表尾
|
||||
r = p; //r指向新的尾结点
|
||||
p->prior = L->prior; //插入到表头
|
||||
L->prior = p;
|
||||
length++;
|
||||
}
|
||||
file.close();
|
||||
} //CreateDuList_L
|
||||
|
||||
int main() {
|
||||
int a, choose;
|
||||
Book e;
|
||||
DuLinkList L, p;
|
||||
cout << "1. 建立\n";
|
||||
cout << "2. 输入\n";
|
||||
cout << "3. 插入\n";
|
||||
cout << "4. 删除\n";
|
||||
cout << "5. 输出\n";
|
||||
cout << "0. 退出\n\n";
|
||||
|
||||
choose = -1;
|
||||
while (choose != 0) {
|
||||
cout << "请选择:";
|
||||
cin >> choose;
|
||||
switch (choose) {
|
||||
case 1: //建立一个双向链表
|
||||
if (InitDuList_L(L))
|
||||
cout << "成功建立双向链表!\n\n";
|
||||
break;
|
||||
case 2: //使用后插法创建双向链表
|
||||
CreateDuList_L(L);
|
||||
cout << "输入 book.txt 信息完毕\n\n";
|
||||
break;
|
||||
case 3: //双向链表的插入
|
||||
cout << "请输入两个数分别代表插入的位置和数值(书的信息:编号&书名&价格):";
|
||||
cin >> a;
|
||||
cin >> e.id >> e.name >> e.price;
|
||||
if (ListInsert_DuL(L, a, e))
|
||||
cout << "插入成功.\n\n";
|
||||
else
|
||||
cout << "插入失败!\n\n";
|
||||
break;
|
||||
case 4: //双向链表的删除
|
||||
cout << "请输入所要删除的书籍的位置:";
|
||||
cin >> a;
|
||||
if (ListDelete_DuL(L, a))
|
||||
cout << "删除成功!\n\n";
|
||||
else
|
||||
cout << "删除失败!\n\n";
|
||||
break;
|
||||
case 5: //双向链表的输出
|
||||
cout << "当前图书系统信息读出:\n";
|
||||
p = L->next;
|
||||
while (p) {
|
||||
cout << left << setw(15) << p->data.id << "\t" << left << setw(
|
||||
50) << p->data.name << "\t" << left << setw(5)
|
||||
<< p->data.price << endl;
|
||||
p = p->next;
|
||||
}
|
||||
cout << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
17
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.13-2.14/book.txt
Normal file
17
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.13-2.14/book.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
ISBN 书名 定价
|
||||
9787302257646 程序设计基础 25
|
||||
9787302219972 单片机技术及应用 32
|
||||
9787302203513 编译原理 46
|
||||
9787811234923 汇编语言程序设计教程 21
|
||||
9787512100831 计算机操作系统 17
|
||||
9787302265436 计算机导论实验指导 18
|
||||
9787302180630 实用数据结构 29
|
||||
9787302225065 数据结构(C语言版) 38
|
||||
9787302171676 C#面向对象程序设计 39
|
||||
9787302250692 C语言程序设计 42
|
||||
9787302150664 数据库原理 35
|
||||
9787302260806 Java编程与实践 56
|
||||
9787302252887 Java程序设计与应用教程 39
|
||||
9787302198505 嵌入式操作系统及编程 25
|
||||
9787302169666 软件测试 24
|
||||
9787811231557 Eclipse基础与应用 35
|
||||
109
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(链表)/2.15(链表).cpp
Normal file
109
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(链表)/2.15(链表).cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<string>
|
||||
using namespace std;
|
||||
|
||||
#define ERROR 0
|
||||
|
||||
typedef struct LNode {
|
||||
int data; //结点的数据域
|
||||
struct LNode *next; //结点的指针域
|
||||
} LNode, *List; //LinkList为指向结构体LNode的指针类型
|
||||
|
||||
int n, m;
|
||||
char st = 'A';
|
||||
|
||||
void InitList(List &L) //创建链表
|
||||
{
|
||||
L = new LNode;
|
||||
L->next = NULL;
|
||||
}
|
||||
|
||||
void ListInput(List &L, int n) //链表数据的输入
|
||||
{
|
||||
int i;
|
||||
List p, r;
|
||||
r = L;
|
||||
char filename[20] = { 0 };
|
||||
cout << "请输入顺序表L" << st << "的数据文件名称(文件名+“.txt”,如List" << st << ".txt):" << endl;
|
||||
++st;
|
||||
gets(filename);
|
||||
fstream file;
|
||||
file.open(filename);
|
||||
if (!file) {
|
||||
cout << "未找到相关文件,无法打开!" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
while (!file.eof()) {
|
||||
p = new LNode;
|
||||
file >> p->data;
|
||||
p->next = NULL;
|
||||
r->next = p;
|
||||
r = p;
|
||||
n++;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
bool LocateElem(List L, int e) //判断List里有没有e这个元素
|
||||
{
|
||||
List p;
|
||||
p = L->next;
|
||||
while (p != NULL) {
|
||||
if (p->data == e)
|
||||
return true;
|
||||
p = p->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ListInsert(List &L, int e) //将e插入到List中
|
||||
{
|
||||
List p;
|
||||
p = new LNode;
|
||||
p->data = e;
|
||||
p->next = L->next;
|
||||
L->next = p;
|
||||
}
|
||||
|
||||
void ListOutput(List L) //输出List
|
||||
{
|
||||
List p;
|
||||
p = L->next;
|
||||
while (p != NULL) {
|
||||
cout << p->data << " ";
|
||||
p = p->next;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void unionList(List &LA, List LB) //算法2.15 线性表的合并(链表)
|
||||
{
|
||||
//将所有在线性表LB中但不在LA中的数据元素插入到LA中
|
||||
int e;
|
||||
List p;
|
||||
p = LB->next;
|
||||
while (p != NULL) {
|
||||
e = p->data;
|
||||
if (!LocateElem(LA, e)) //LA中不存在和e相同的数据元素,则插入之
|
||||
ListInsert(LA, e);
|
||||
p = p->next;
|
||||
}
|
||||
} //unionList
|
||||
|
||||
int main() {
|
||||
List LA, LB;
|
||||
|
||||
InitList(LA);
|
||||
|
||||
InitList(LB);
|
||||
|
||||
ListInput(LA, n);
|
||||
ListInput(LB, m);
|
||||
|
||||
unionList(LA, LB);
|
||||
|
||||
cout << "LA和LB合并后的集合为:\n";
|
||||
ListOutput(LA);
|
||||
return 0;
|
||||
}
|
||||
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(链表)/ListA.txt
Normal file
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(链表)/ListA.txt
Normal file
@@ -0,0 +1 @@
|
||||
7 5 3 11
|
||||
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(链表)/ListB.txt
Normal file
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(链表)/ListB.txt
Normal file
@@ -0,0 +1 @@
|
||||
2 6 3
|
||||
100
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(顺序表)/2.15(顺序表).cpp
Normal file
100
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(顺序表)/2.15(顺序表).cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 100
|
||||
#define ERROR 0
|
||||
typedef struct { //定义顺序表
|
||||
int *elem;
|
||||
int length;
|
||||
} List;
|
||||
int n, m;
|
||||
char st = 'A';
|
||||
|
||||
void InitList(List &L) //创建顺序表
|
||||
{
|
||||
L.elem = new int[MAXSIZE];
|
||||
L.length = 0;
|
||||
}
|
||||
|
||||
void ListInput(List &L, int n) //顺序表数据的输入
|
||||
{
|
||||
int i = 0;
|
||||
char filename[20] = { 0 };
|
||||
cout << "请输入顺序表L" << st << "的数据文件名称(文件名+“.txt”,如List" << st << ".txt):" << endl;
|
||||
++st;
|
||||
gets(filename);
|
||||
fstream file;
|
||||
file.open(filename);
|
||||
if (!file) {
|
||||
cout << "未找到相关文件,无法打开!" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
while (!file.eof()) {
|
||||
file >> L.elem[i];
|
||||
i++;
|
||||
}
|
||||
L.length = i;
|
||||
|
||||
}
|
||||
|
||||
int ListLength(List L) //求顺序表的长度
|
||||
{
|
||||
return L.length;
|
||||
}
|
||||
|
||||
void GetElem(List L, int i, int &e) //求顺序表的第i个元素,并以e返回
|
||||
{
|
||||
e = L.elem[i - 1];
|
||||
}
|
||||
|
||||
bool LocateElem(List L, int e) //判断List里有没有e这个元素
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < L.length; i++)
|
||||
if (e == L.elem[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ListInsert(List &L, int e) //将e插入到List的最后
|
||||
{
|
||||
L.elem[L.length] = e;
|
||||
L.length++;
|
||||
}
|
||||
|
||||
void ListOutput(List L) //输出List
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < L.length; i++)
|
||||
cout << L.elem[i] << " ";
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void unionList(List &LA, List LB) //算法2.14 线性表的合并(顺序表)
|
||||
{
|
||||
//将所有在线性表LB中但不在LA中的数据元素插入到LA中
|
||||
int LA_len, LB_len, i, e;
|
||||
LA_len = ListLength(LA);
|
||||
LB_len = ListLength(LB); //求线性表的长度
|
||||
for (i = 1; i <= LB_len; i++) {
|
||||
GetElem(LB, i, e); //取LB中第i个数据元素赋给e
|
||||
if (!LocateElem(LA, e)) //LA中不存在和e相同的数据元素,则插入之
|
||||
ListInsert(LA, e);
|
||||
}
|
||||
} //unionList
|
||||
|
||||
int main() {
|
||||
List LA, LB;
|
||||
InitList(LA);
|
||||
InitList(LB);
|
||||
|
||||
ListInput(LA, n);
|
||||
|
||||
ListInput(LB, m);
|
||||
|
||||
unionList(LA, LB);
|
||||
|
||||
cout << "LA和LB合并后的集合为:\n";
|
||||
ListOutput(LA);
|
||||
return 0;
|
||||
}
|
||||
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(顺序表)/ListA.txt
Normal file
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(顺序表)/ListA.txt
Normal file
@@ -0,0 +1 @@
|
||||
7 5 3 11
|
||||
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(顺序表)/ListB.txt
Normal file
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.15(顺序表)/ListB.txt
Normal file
@@ -0,0 +1 @@
|
||||
2 6 3
|
||||
93
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.16/2.16.cpp
Normal file
93
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.16/2.16.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 100
|
||||
#define ERROR 0
|
||||
|
||||
typedef struct //定义顺序表
|
||||
{
|
||||
int *elem;
|
||||
int length;
|
||||
} SqList;
|
||||
int num_a = 0, num_b = 0;
|
||||
char st = 'A';
|
||||
|
||||
void InitList_Sq(SqList &L, int n) //创建顺序表
|
||||
{
|
||||
L.elem = new int[MAXSIZE];
|
||||
if (!L.elem)
|
||||
exit(0);
|
||||
L.length = 0;
|
||||
}
|
||||
|
||||
void input(SqList &L, int n) //依次往顺序表L里输入数据
|
||||
{
|
||||
int i = 0;
|
||||
char filename[20] = { 0 };
|
||||
cout << "请输入非递减线性表" << st << "的数据文件名称(文件名+“.txt”,如List" << st << ".txt):" << endl;
|
||||
++st;
|
||||
gets(filename);
|
||||
fstream file;
|
||||
file.open(filename);
|
||||
if (!file) {
|
||||
cout << "未找到相关文件,无法打开!" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
while (!file.eof()) {
|
||||
file >> L.elem[i];
|
||||
i++;
|
||||
}
|
||||
L.length = i;
|
||||
}
|
||||
|
||||
void output(SqList L) //依次输出顺序表里的每个元素
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < L.length; i++) {
|
||||
if (i)
|
||||
cout << ",";
|
||||
cout << L.elem[i];
|
||||
}
|
||||
}
|
||||
|
||||
void MergeList_Sq(SqList LA, SqList LB, SqList &LC) //算法2.16 顺序有序表的合并
|
||||
{
|
||||
//已知顺序有序表LA和LB的元素按值非递减排列
|
||||
//归并LA和LB得到新的顺序有序表LC,LC的元素也按值非递减排列
|
||||
int *pa, *pb, *pc, *pa_last, *pb_last;
|
||||
pa = LA.elem;
|
||||
pb = LB.elem; //指针pa和pb的初值分别指向两个表的第一次元素
|
||||
LC.length = LA.length + LB.length; //新表长度为待合并两表的长度之和
|
||||
LC.elem = new int[LC.length]; //为合并后的新表分配一个数组空间
|
||||
pc = LC.elem; //指针pc指向新表的第一个元素
|
||||
pa_last = LA.elem + LA.length - 1; //指针pa_last指向LA表的最后一个元素
|
||||
pb_last = LB.elem + LB.length - 1; //指针pb_last指向LB表的最后一个元素
|
||||
while (pa <= pa_last && pb <= pb_last) //两个表都非空
|
||||
{
|
||||
if (*pa <= *pb) //依次“摘取”两表中值较小的结点插入到LC表的最后
|
||||
*pc++ = *pa++;
|
||||
else
|
||||
*pc++ = *pb++;
|
||||
}
|
||||
while (pa <= pa_last) //LB已到达表尾,依次将LA的剩余元素插入LC表的最后
|
||||
*pc++ = *pa++;
|
||||
while (pb <= pb_last) //LA已到达表尾,依次将LB的剩余元素插入LC表的最后
|
||||
*pc++ = *pb++;
|
||||
} //MergeList_List
|
||||
|
||||
int main() {
|
||||
SqList La, Lb, Lc;
|
||||
|
||||
InitList_Sq(La, num_a); //La表的创建
|
||||
input(La, num_a); //依次往顺序表La里输入数据
|
||||
|
||||
InitList_Sq(Lb, num_b); //Lb表的创建
|
||||
input(Lb, num_b); //依次往顺序表La里输入数据
|
||||
|
||||
MergeList_Sq(La, Lb, Lc); //将顺序表La和Lb进行合并
|
||||
|
||||
cout << "非递减线性表A,B合并后的非递减线性表C为:\n"; //输出合并后的有序顺序表Lc
|
||||
output(Lc);
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.16/ListA.txt
Normal file
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.16/ListA.txt
Normal file
@@ -0,0 +1 @@
|
||||
3 5 8 11
|
||||
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.16/ListB.txt
Normal file
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.16/ListB.txt
Normal file
@@ -0,0 +1 @@
|
||||
2 6 8 9 11 15 20
|
||||
104
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.17/2.17.cpp
Normal file
104
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.17/2.17.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
using namespace std;
|
||||
#define ERROR 0
|
||||
|
||||
typedef struct LNode //定义单链表
|
||||
{
|
||||
int data;
|
||||
struct LNode *next;
|
||||
} LNode, *LinkList;
|
||||
|
||||
int num_a, num_b;
|
||||
char st = 'A';
|
||||
|
||||
void InitList_L(LinkList &L) //创建单链表
|
||||
{
|
||||
L = new LNode;
|
||||
L->next = NULL;
|
||||
}
|
||||
|
||||
void input(LinkList &L, int n) //依次往单链表L里输入数据
|
||||
{
|
||||
int i;
|
||||
LNode *p, *r;
|
||||
r = L;
|
||||
char filename[20] = { 0 };
|
||||
cout << "请输入非递减单链表" << st << "的数据文件名称(文件名+“.txt”,如List" << st << ".txt):" << endl;
|
||||
++st;
|
||||
gets(filename);
|
||||
fstream file;
|
||||
file.open(filename);
|
||||
if (!file) {
|
||||
cout << "未找到相关文件,无法打开!" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
while (!file.eof()) {
|
||||
p = new LNode;
|
||||
file >> p->data;
|
||||
p->next = NULL;
|
||||
r->next = p;
|
||||
r = p;
|
||||
n++;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
void output(LinkList L) //依次输出单链表里的每个元素
|
||||
{
|
||||
int i = 0;
|
||||
LNode *p;
|
||||
p = L->next;
|
||||
while (p) {
|
||||
if (i)
|
||||
cout << ",";
|
||||
cout << p->data;
|
||||
p = p->next;
|
||||
i = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void MergeList_L(LinkList &LA, LinkList &LB, LinkList &LC) //算法2.17 链式有序表的合并
|
||||
{
|
||||
//已知单链表LA和LB的元素按值非递减排列
|
||||
//归并LA和LB得到新的单链表LC,LC的元素也按值非递减排列
|
||||
LinkList pa, pb, pc;
|
||||
pa = LA->next;
|
||||
pb = LB->next; //pa和pb的初值分别指向两个表的第一个结点
|
||||
LC = LA; //用LA的头结点作为LC的头结点
|
||||
pc = LC; //pc的初值指向LC的头结点
|
||||
while (pa && pb) //两个表都非空
|
||||
{
|
||||
if (pa->data <= pb->data) //依次"摘取"两表中值较小的结点插入到LC表的最后
|
||||
{
|
||||
pc->next = pa; //将pa所指结点链接到pc所指结点之后
|
||||
pc = pa;
|
||||
pa = pa->next;
|
||||
} else {
|
||||
pc->next = pb; //将pb所指结点链接到pc所指结点之后
|
||||
pc = pb;
|
||||
pb = pb->next;
|
||||
}
|
||||
}
|
||||
pc->next = pa ? pa : pb; //插入非空表的剩余段
|
||||
delete LB; //释放LB的头结点
|
||||
} //MergeList_L()
|
||||
|
||||
int main() {
|
||||
LinkList La, Lb, Lc;
|
||||
|
||||
InitList_L(La); //La表的创建
|
||||
input(La, num_a); //依次往单链表La里输入数据
|
||||
|
||||
InitList_L(Lb); //Lb表的创建
|
||||
input(Lb, num_b); //依次往单链表La里输入数据
|
||||
|
||||
InitList_L(Lc);
|
||||
MergeList_L(La, Lb, Lc); //将单链表La和Lb进行合并
|
||||
|
||||
|
||||
cout << "非递减单链表A,B合并后的非递减单链表C为:\n"; //输出合并后的单链表Lc
|
||||
output(Lc);
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.17/ListA.txt
Normal file
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.17/ListA.txt
Normal file
@@ -0,0 +1 @@
|
||||
3 5 8 11
|
||||
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.17/ListB.txt
Normal file
1
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.17/ListB.txt
Normal file
@@ -0,0 +1 @@
|
||||
2 6 8 9 11 15 20
|
||||
124
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.18-2.19/2.18-2.19.cpp
Normal file
124
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.18-2.19/2.18-2.19.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
#include<fstream>
|
||||
using namespace std;
|
||||
#define ERROR 0
|
||||
|
||||
typedef struct PNode {
|
||||
float coef; //系数
|
||||
int expn; //指数
|
||||
struct PNode *next;
|
||||
} PNode, *Polynomial;
|
||||
string head_1, head_2;
|
||||
int temp;
|
||||
char st = 'A';
|
||||
|
||||
void CreatPolyn(Polynomial &P, int m) //算法2.18 多项式的创建
|
||||
{
|
||||
//输入m项的系数和指数,建立表示一个多项式的有序链表P
|
||||
Polynomial q, pre, s;
|
||||
int i;
|
||||
P = new PNode;
|
||||
P->next = NULL; //先建立一个带头结点的单链表
|
||||
char filename[20] = { 0 };
|
||||
cout << "请输入有关多项式p" << char(st + 32) << "系数和指数的数据文件名称(文件名+“.txt”,如Poly" << st << ".txt):" << endl;
|
||||
++st;
|
||||
gets(filename);
|
||||
fstream file;
|
||||
file.open(filename);
|
||||
if (!file) {
|
||||
cout << "未找到相关文件,无法打开!" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
file >> head_1 >> head_2;
|
||||
while (!file.eof())
|
||||
{
|
||||
s = new PNode; //生成新结点
|
||||
file >> s->coef >> s->expn; //输入元素值
|
||||
pre = P; //pre用于保存q的前驱,初值为头结点
|
||||
q = P->next;
|
||||
while (q && q->expn < s->expn) //通过比较指数找到第一个大于输入项指数的项q
|
||||
{
|
||||
pre = q;
|
||||
q = q->next;
|
||||
} //while
|
||||
s->next = q; //将输入项s插入到q和其前驱结点pre之间
|
||||
pre->next = s;
|
||||
}//for
|
||||
file.close();
|
||||
} //CreatPolyn
|
||||
|
||||
void AddPolyn(Polynomial &Pa, Polynomial &Pb) //算法2.19 多项式的相加
|
||||
{
|
||||
//多项式加法:Pa=Pa+Pb,利用两个多项式的结点构成“和多项式”
|
||||
Polynomial r, p1, p2, p3;
|
||||
float sum;
|
||||
p1 = Pa->next;
|
||||
p2 = Pb->next; //p1和p2初值分别指向Pa和Pb的第一个结点
|
||||
p3 = Pa; //p3指向和多项式的当前结点,初值为Pa
|
||||
while (p1 && p2) //p1和p2均非空
|
||||
{
|
||||
if (p1->expn == p2->expn) //指数相等
|
||||
{
|
||||
sum = p1->coef + p2->coef; //sum保存两项的系数和
|
||||
if (sum != 0) //系数和不为0
|
||||
{
|
||||
p1->coef = sum; //修改Pa当前结点p1的系数值为两项系数的和
|
||||
p3->next = p1;
|
||||
p3 = p1; //将修改后的Pa当前结点p1链在p3之后,p3指向p1
|
||||
p1 = p1->next; //p1指向后一项
|
||||
r = p2;
|
||||
p2 = p2->next;
|
||||
delete r; //删除Pb当前结点r
|
||||
} else //系数和为0
|
||||
{
|
||||
r = p1;
|
||||
p1 = p1->next;
|
||||
delete r; //删除Pb当前结点p1
|
||||
r = p2;
|
||||
p2 = p2->next;
|
||||
delete r; //删除Pb当前结点p2
|
||||
}
|
||||
} else if (p1->expn < p2->expn) //Pa当前结点p1的指数值小
|
||||
{
|
||||
p3->next = p1; //将p1链在p3之后
|
||||
p3 = p1; //p3指向p1
|
||||
p1 = p1->next; //p1指向后一项
|
||||
} else //Pa当前结点p2的指数值小
|
||||
{
|
||||
p3->next = p2; //将p2链在p3之后
|
||||
p3 = p2; //p3指向p2
|
||||
p2 = p2->next; //p2指向后一项
|
||||
}
|
||||
} //while
|
||||
p3->next = p1 ? p1 : p2; //插入非空多项式的剩余段
|
||||
delete Pb; //释放Pb的头结点
|
||||
} //AddPolyn
|
||||
|
||||
|
||||
int main() {
|
||||
Polynomial Pa, Pb;
|
||||
Polynomial p;
|
||||
int i;
|
||||
|
||||
//创建多项式Pa
|
||||
CreatPolyn(Pa, temp); //调用函数,输入Pa每一项的系数和指数
|
||||
|
||||
//创建多项式Pb
|
||||
CreatPolyn(Pb, temp); //调用函数,输入Pa每一项的系数和指数
|
||||
|
||||
AddPolyn(Pa, Pb);
|
||||
cout << "多项式Pa和Pb相加后的结果是:\n";
|
||||
p = Pa->next;
|
||||
i = 0;
|
||||
while (p) //输出相加后的结果,每一项以x^n表示
|
||||
{
|
||||
if (i)
|
||||
cout << " + ";
|
||||
cout << "(" << p->coef << ") * x^" << p->expn;
|
||||
p = p->next;
|
||||
i = 1;
|
||||
}
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
5
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.18-2.19/PolyA.txt
Normal file
5
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.18-2.19/PolyA.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
系数p 指数
|
||||
7 0
|
||||
3 1
|
||||
9 8
|
||||
5 17
|
||||
4
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.18-2.19/PolyB.txt
Normal file
4
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.18-2.19/PolyB.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
系数p 指数
|
||||
8 1
|
||||
22 7
|
||||
-9 8
|
||||
227
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.6-2.12/2.6-2.12.cpp
Normal file
227
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.6-2.12/2.6-2.12.cpp
Normal file
@@ -0,0 +1,227 @@
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
#include<iomanip>
|
||||
#include<fstream>
|
||||
using namespace std;
|
||||
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。
|
||||
typedef int ElemType; //ElemType 为可定义的数据类型,此设为int类型
|
||||
|
||||
struct Book {
|
||||
string id;//ISBN
|
||||
string name;//书名
|
||||
double price;//定价
|
||||
};
|
||||
typedef struct LNode {
|
||||
Book data; //结点的数据域
|
||||
struct LNode *next; //结点的指针域
|
||||
} LNode, *LinkList; //LinkList为指向结构体LNode的指针类型
|
||||
|
||||
string head_1, head_2, head_3;
|
||||
int length;
|
||||
|
||||
Status InitList_L(LinkList &L) { //算法2.6 单链表的初始化
|
||||
//构造一个空的单链表L
|
||||
L = new LNode; //生成新结点作为头结点,用头指针L指向头结点
|
||||
L->next = NULL; //头结点的指针域置空
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status GetElem_L(LinkList L, int i, Book &e) { //算法2.7 单链表的取值
|
||||
//在带头结点的单链表L中查找第i个元素
|
||||
//用e返回L中第i个数据元素的值
|
||||
int j;
|
||||
LinkList p;
|
||||
p = L->next;
|
||||
j = 1; //初始化,p指向第一个结点,j为计数器
|
||||
while (j < i && p) { //顺链域向后扫描,直到p指向第i个元素或p为空
|
||||
p = p->next; //p指向下一个结点
|
||||
++j; //计数器j相应加1
|
||||
}
|
||||
if (!p || j > i)
|
||||
return ERROR; //i值不合法i>n或i<=0
|
||||
e = p->data; //取第i个结点的数据域
|
||||
return OK;
|
||||
} //GetElem_L
|
||||
|
||||
LNode *LocateElem_L(LinkList L, int e) { //算法2.8 按值查找
|
||||
//在带头结点的单链表L中查找值为e的元素
|
||||
LinkList p;
|
||||
p = L->next;
|
||||
while (p && p->data.price != e)//顺链域向后扫描,直到p为空或p所指结点的数据域等于e
|
||||
p = p->next; //p指向下一个结点
|
||||
return p; //查找成功返回值为e的结点地址p,查找失败p为NULL
|
||||
} //LocateElem_L
|
||||
|
||||
Status ListInsert_L(LinkList &L, int i, Book &e) { //算法2.9 单链表的插入
|
||||
//在带头结点的单链表L中第i个位置插入值为e的新结点
|
||||
int j;
|
||||
LinkList p, s;
|
||||
p = L;
|
||||
j = 0;
|
||||
while (p && j < i - 1) {
|
||||
p = p->next;
|
||||
++j;
|
||||
}//查找第i?1个结点,p指向该结点
|
||||
if (!p || j > i - 1)
|
||||
return ERROR; //i>n+1或者i<1
|
||||
s = new LNode; //生成新结点*s
|
||||
s->data = e; //将结点*s的数据域置为e
|
||||
s->next = p->next; //将结点*s的指针域指向结点ai
|
||||
p->next = s; //将结点*p的指针域指向结点*s
|
||||
++length;
|
||||
return OK;
|
||||
} //ListInsert_L
|
||||
|
||||
Status ListDelete_L(LinkList &L, int i) { //算法2.9 单链表的删除
|
||||
//在带头结点的单链表L中,删除第i个位置
|
||||
LinkList p, q;
|
||||
int j;
|
||||
p = L;
|
||||
j = 0;
|
||||
while ((p->next) && (j < i - 1)) //查找第i?1个结点,p指向该结点
|
||||
{
|
||||
p = p->next;
|
||||
++j;
|
||||
}
|
||||
if (!(p->next) || (j > i - 1))
|
||||
return ERROR; //当i>n或i<1时,删除位置不合理
|
||||
q = p->next; //临时保存被删结点的地址以备释放
|
||||
p->next = q->next; //改变删除结点前驱结点的指针域
|
||||
delete q; //释放删除结点的空间
|
||||
--length;
|
||||
return OK;
|
||||
} //ListDelete_L
|
||||
|
||||
void CreateList_H(LinkList &L, int n) { //算法2.11 前插法创建单链表
|
||||
//逆位序输入n个元素的值,建立到头结点的单链表L
|
||||
LinkList p;
|
||||
L = new LNode;
|
||||
L->next = NULL; //先建立一个带头结点的空链表
|
||||
length = 0;
|
||||
fstream file;
|
||||
file.open("book.txt");
|
||||
if (!file) {
|
||||
cout << "未找到相关文件,无法打开!" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
file >> head_1 >> head_2 >> head_3;
|
||||
while (!file.eof()) {
|
||||
p = new LNode; //生成新结点*p
|
||||
file >> p->data.id >> p->data.name >> p->data.price; //输入元素值赋给新结点*p的数据域
|
||||
p->next = L->next;
|
||||
L->next = p; //将新结点*p插入到头结点之后
|
||||
length++;//同时对链表长度进行统计
|
||||
}
|
||||
file.close();
|
||||
} //CreateList_F
|
||||
|
||||
void CreateList_R(LinkList &L, int n) { //算法2.12 后插法创建单链表
|
||||
//正位序输入n个元素的值,建立带表头结点的单链表L
|
||||
LinkList p, r;
|
||||
L = new LNode;
|
||||
L->next = NULL; //先建立一个带头结点的空链表
|
||||
r = L; //尾指针r指向头结点
|
||||
length = 0;
|
||||
fstream file; //打开文件进行读写操作
|
||||
file.open("book.txt");
|
||||
if (!file) {
|
||||
cout << "未找到相关文件,无法打开!" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
file >> head_1 >> head_2 >> head_3;
|
||||
while (!file.eof()) { //将文件中的信息运用后插法插入到链表中
|
||||
p = new LNode;//生成新结点
|
||||
file >> p->data.id >> p->data.name >> p->data.price;//输入元素值赋给新结点*p的数据域
|
||||
p->next = NULL;
|
||||
r->next = p;//将新结点*p插入尾结点*r之后
|
||||
r = p;//r指向新的尾结点*p
|
||||
length++; //同时对链表长度进行统计
|
||||
}
|
||||
file.close();
|
||||
} //CreateList_L
|
||||
|
||||
int main() {
|
||||
int a, n, choose;
|
||||
double price;
|
||||
Book e;
|
||||
LinkList L, p;
|
||||
cout << "1. 建立\n";
|
||||
cout << "2. 输入\n";
|
||||
cout << "3. 取值\n";
|
||||
cout << "4. 查找\n";
|
||||
cout << "5. 插入\n";
|
||||
cout << "6. 删除\n";
|
||||
cout << "7. 输出\n";
|
||||
cout << "0. 退出\n\n";
|
||||
|
||||
choose = -1;
|
||||
while (choose != 0) {
|
||||
cout << "请选择:";
|
||||
cin >> choose;
|
||||
switch (choose) {
|
||||
case 1: //建立一个单链表
|
||||
if (InitList_L(L))
|
||||
cout << "成功建立链表!\n\n";
|
||||
break;
|
||||
case 2: //使用后插法创建单链表
|
||||
CreateList_R(L, length);
|
||||
cout << "输入 book.txt 信息完毕\n\n";
|
||||
break;
|
||||
case 3: //单链表的按序号取值
|
||||
cout << "请输入一个位置用来取值:";
|
||||
cin >> a;
|
||||
if (GetElem_L(L, a, e)) {
|
||||
cout << "查找成功\n";
|
||||
cout << "第" << a << "本图书的信息是:\n";
|
||||
cout << left << setw(15) << e.id << "\t" << left << setw(50)
|
||||
<< e.name << "\t" << left << setw(5) << e.price << endl
|
||||
<< endl;
|
||||
} else
|
||||
cout << "查找失败\n\n";
|
||||
break;
|
||||
case 4: //单链表的按值查找
|
||||
cout << "请输入所要查找价格:";
|
||||
cin >> price;
|
||||
if (LocateElem_L(L, price) != NULL) {
|
||||
cout << "查找成功\n";
|
||||
cout << "该价格对应的书名为:" << LocateElem_L(L, price)->data.name
|
||||
<< endl << endl;
|
||||
} else
|
||||
cout << "查找失败! 定价" << price << " 没有找到\n\n";
|
||||
break;
|
||||
case 5: //单链表的插入
|
||||
cout << "请输入插入的位置和书的信息,包括:编号 书名 价格(用空格隔开):";
|
||||
cin >> a;
|
||||
cin >> e.id >> e.name >> e.price;
|
||||
if (ListInsert_L(L, a, e))
|
||||
cout << "插入成功.\n\n";
|
||||
else
|
||||
cout << "插入失败!\n\n";
|
||||
break;
|
||||
case 6: //单链表的删除
|
||||
cout << "请输入所要删除的书籍的位置:";
|
||||
cin >> a;
|
||||
if (ListDelete_L(L, a))
|
||||
cout << "删除成功!\n\n";
|
||||
else
|
||||
cout << "删除失败!\n\n";
|
||||
break;
|
||||
case 7: //单链表的输出
|
||||
cout << "当前图书系统信息(链表)读出:\n";
|
||||
p = L->next;
|
||||
while (p) {
|
||||
cout << left << setw(15) << p->data.id << "\t" << left << setw(
|
||||
50) << p->data.name << "\t" << left << setw(5)
|
||||
<< p->data.price << endl;
|
||||
p = p->next;
|
||||
}
|
||||
cout << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
17
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.6-2.12/book.txt
Normal file
17
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第2章/2.6-2.12/book.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
ISBN 书名 定价
|
||||
9787302257646 程序设计基础 25
|
||||
9787302219972 单片机技术及应用 32
|
||||
9787302203513 编译原理 46
|
||||
9787811234923 汇编语言程序设计教程 21
|
||||
9787512100831 计算机操作系统 17
|
||||
9787302265436 计算机导论实验指导 18
|
||||
9787302180630 实用数据结构 29
|
||||
9787302225065 数据结构(C语言版) 38
|
||||
9787302171676 C#面向对象程序设计 39
|
||||
9787302250692 C语言程序设计 42
|
||||
9787302150664 数据库原理 35
|
||||
9787302260806 Java编程与实践 56
|
||||
9787302252887 Java程序设计与应用教程 39
|
||||
9787302198505 嵌入式操作系统及编程 25
|
||||
9787302169666 软件测试 24
|
||||
9787811231557 Eclipse基础与应用 35
|
||||
117
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.1-3.4/3.1-3.4.cpp
Normal file
117
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.1-3.4/3.1-3.4.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
/***顺序栈的实现***/
|
||||
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
using namespace std;
|
||||
|
||||
//顺序栈定义
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
#define MAXSIZE 100//顺序栈存储空间的初始分配量
|
||||
typedef int Status;
|
||||
typedef char SElemType;
|
||||
|
||||
typedef struct {
|
||||
SElemType *base;//栈底指针
|
||||
SElemType *top;//栈顶指针
|
||||
int stacksize;//栈可用的最大容量
|
||||
} SqStack;
|
||||
|
||||
//算法3.1 顺序栈的初始化
|
||||
Status InitStack(SqStack &S) {
|
||||
//构造一个空栈S
|
||||
S.base = new SElemType[MAXSIZE];//为顺序栈动态分配一个最大容量为MAXSIZE的数组空间
|
||||
if (!S.base)
|
||||
exit(OVERFLOW); //存储分配失败
|
||||
S.top = S.base; //top初始为base,空栈
|
||||
S.stacksize = MAXSIZE; //stacksize置为栈的最大容量MAXSIZE
|
||||
return OK;
|
||||
}
|
||||
//算法3.2 顺序栈的入栈
|
||||
Status Push(SqStack &S, SElemType e) {
|
||||
// 插入元素e为新的栈顶元素
|
||||
if (S.top - S.base == S.stacksize)
|
||||
return ERROR; //栈满
|
||||
*(S.top++) = e; //元素e压入栈顶,栈顶指针加1
|
||||
return OK;
|
||||
}
|
||||
//算法3.3 顺序栈的出栈
|
||||
Status Pop(SqStack &S, SElemType &e) {
|
||||
//删除S的栈顶元素,用e返回其值
|
||||
if (S.base == S.top)
|
||||
return ERROR;//栈空
|
||||
e = *(--S.top); //栈顶指针减1,将栈顶元素赋给e
|
||||
return OK;
|
||||
}
|
||||
//算法3.4 取顺序栈的栈顶元素
|
||||
char GetTop(SqStack S) {//返回S的栈顶元素,不修改栈顶指针
|
||||
if (S.top != S.base) //栈非空
|
||||
return *(S.top - 1); //返回栈顶元素的值,栈顶指针不变
|
||||
}
|
||||
|
||||
int main() {
|
||||
SqStack s;
|
||||
int choose, flag = 0;
|
||||
SElemType j, e, t;
|
||||
cout << "1.初始化\n";
|
||||
cout << "2.入栈\n";
|
||||
cout << "3.读栈顶元素\n";
|
||||
cout << "4.出栈\n";
|
||||
cout << "0.退出\n\n";
|
||||
|
||||
choose = -1;
|
||||
while (choose != 0) {
|
||||
cout << "请选择:";
|
||||
cin >> choose;
|
||||
switch (choose) {
|
||||
case 1://算法3.1 顺序栈的初始化
|
||||
if (InitStack(s)) {
|
||||
flag = 1;
|
||||
cout << "成功对栈进行初始化\n\n";
|
||||
} else
|
||||
cout << "初始化栈失败\n\n";
|
||||
break;
|
||||
case 2: {//算法3.2 顺序栈的入栈
|
||||
fstream file;
|
||||
file.open("SqStack.txt");//
|
||||
if (!file) {
|
||||
cout << "错误!未找到文件!\n\n" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
if (flag) {
|
||||
flag = 1;
|
||||
cout << "进栈元素依次为:\n";
|
||||
while (!file.eof()) {
|
||||
file >> j;
|
||||
if (file.fail())
|
||||
break;
|
||||
else {
|
||||
Push(s, j);
|
||||
cout << j << " ";
|
||||
}
|
||||
}
|
||||
cout << endl << endl;
|
||||
} else
|
||||
cout << "栈未建立,请重新选择\n\n";
|
||||
file.close();
|
||||
}
|
||||
break;
|
||||
case 3://算法3.3 顺序栈的出栈
|
||||
if(flag != -1 && flag != 0)
|
||||
cout << "栈顶元素为:\n" << GetTop(s) << endl << endl;
|
||||
else
|
||||
cout << "栈中无元素,请重新选择\n" << endl;
|
||||
break;
|
||||
case 4://算法3.4 取顺序栈的栈顶元素
|
||||
cout << "依次弹出的栈顶元素为:\n";
|
||||
while (Pop(s, t)){
|
||||
flag = -1;
|
||||
cout << t << " ";
|
||||
}
|
||||
cout << endl << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
4
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.1-3.4/SqStack.txt
Normal file
4
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.1-3.4/SqStack.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
A
|
||||
B
|
||||
C
|
||||
D
|
||||
16
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.10/3.10.cpp
Normal file
16
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.10/3.10.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
/***Hanoi塔问题***/
|
||||
|
||||
#include"3.10.h"
|
||||
|
||||
int main() {
|
||||
int n;
|
||||
char a, b, c;
|
||||
a = '1';
|
||||
b = '2';
|
||||
c = '3';
|
||||
cout << "请输入初始第一个柱子上的圆盘个数:" << endl;
|
||||
cin >> n;
|
||||
cout << "将第一个柱子上的圆盘全部移动到第三个柱子上的过程为:" << endl;
|
||||
Hanoi(n, a, b, c);
|
||||
return 0;
|
||||
}
|
||||
20
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.10/3.10.h
Normal file
20
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.10/3.10.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
int m = 0;//(m是初值为0的全局变量,对搬动计数)
|
||||
void move(char A, int n, char C) // 搬动操作
|
||||
{
|
||||
cout << "第" << ++m << "步," << "将编号为" << n << "的圆盘从第" << A << "个柱子上移到第" << C
|
||||
<< "个柱子上" << endl;
|
||||
}
|
||||
|
||||
//算法3.10 Hanoi塔问题的递归算法
|
||||
void Hanoi(int n, char A, char B, char C) {//将塔座A上的n个圆盘按规则搬到C上,B做辅助塔
|
||||
if (n == 1)
|
||||
move(A, 1, C); //将编号为1的圆盘从A移到C
|
||||
else {
|
||||
Hanoi(n - 1, A, C, B); //将A上编号为1至n-1的圆盘移到B,C做辅助塔
|
||||
move(A, n, C);//将编号为n的圆盘从A移到C
|
||||
Hanoi(n - 1, B, A, C); //将B上编号为1至n-1的圆盘移到C,A做辅助塔
|
||||
}
|
||||
}
|
||||
123
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.11-3.15/3.11-3.15.cpp
Normal file
123
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.11-3.15/3.11-3.15.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
/***循环队列基本操作***/
|
||||
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
using namespace std;
|
||||
|
||||
#define MAXQSIZE 100
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef char QElemType;
|
||||
typedef char SElemType;
|
||||
typedef int Status;
|
||||
|
||||
typedef struct {
|
||||
QElemType *base;//初始化时动态分配存储空间
|
||||
int front;//头指针
|
||||
int rear;//尾指针
|
||||
} SqQueue;
|
||||
|
||||
//算法3.11 循环队列的初始化
|
||||
Status InitQueue(SqQueue &Q) {//构造一个空队列Q
|
||||
Q.base = new QElemType[MAXQSIZE]; //为队列分配一个最大容量为MAXSIZE的数组空间
|
||||
if (!Q.base)
|
||||
exit(OVERFLOW); //存储分配失败
|
||||
Q.front = Q.rear = 0; //头指针和尾指针置为零,队列为空
|
||||
return OK;
|
||||
}
|
||||
|
||||
//算法3.12 求循环队列的长度
|
||||
int QueueLength(SqQueue Q) {//返回Q的元素个数,即队列的长度
|
||||
return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
|
||||
}
|
||||
|
||||
//算法3.13 循环队列的入队
|
||||
Status EnQueue(SqQueue &Q, QElemType e) {//插入元素e为Q的新的队尾元素
|
||||
if ((Q.rear + 1) % MAXQSIZE == Q.front) //尾指针在循环意义上加1后等于头指针,表明队满
|
||||
return ERROR;
|
||||
Q.base[Q.rear] = e; //新元素插入队尾
|
||||
Q.rear = (Q.rear + 1) % MAXQSIZE; //队尾指针加1
|
||||
return OK;
|
||||
}
|
||||
|
||||
//算法3.14 循环队列的出队
|
||||
Status DeQueue(SqQueue &Q, QElemType &e) {//删除Q的队头元素,用e返回其值
|
||||
if (Q.front == Q.rear)
|
||||
return ERROR; //队空
|
||||
e = Q.base[Q.front]; //保存队头元素
|
||||
Q.front = (Q.front + 1) % MAXQSIZE; //队头指针加1
|
||||
return OK;
|
||||
}
|
||||
|
||||
//算法3.15 取循环队列的队头元素
|
||||
SElemType GetHead(SqQueue Q) {//返回Q的队头元素,不修改队头指针
|
||||
if (Q.front != Q.rear) //队列非空
|
||||
return Q.base[Q.front]; //返回队头元素的值,队头指针不变
|
||||
}
|
||||
|
||||
int main() {
|
||||
int choose, flag = 0;
|
||||
SqQueue Q;
|
||||
QElemType e, j;
|
||||
cout << "1.初始化\n";
|
||||
cout << "2.入队\n";
|
||||
cout << "3.读队头元素\n";
|
||||
cout << "4.出队\n";
|
||||
cout << "0.退出\n\n";
|
||||
|
||||
choose = -1;
|
||||
while (choose != 0) {
|
||||
cout << "请选择:";
|
||||
cin >> choose;
|
||||
switch (choose) {
|
||||
case 1://算法3.16 链队的初始化
|
||||
if (InitQueue(Q)) {
|
||||
flag = 1;
|
||||
cout << "成功对队列进行初始化\n\n";
|
||||
} else
|
||||
cout << "初始化队列失败\n\n";
|
||||
break;
|
||||
case 2: {//算法3.17 链队的入队
|
||||
fstream file;
|
||||
file.open("QNode.txt");
|
||||
if (!file) {
|
||||
cout << "错误!未找到文件!\n\n" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
if (flag) {
|
||||
flag = 1;
|
||||
cout << "入队的元素依次为:\n";
|
||||
while (!file.eof()) {
|
||||
file >> j;
|
||||
if (file.fail())
|
||||
break;
|
||||
else {
|
||||
EnQueue(Q, j);
|
||||
cout << j << " ";
|
||||
}
|
||||
}
|
||||
cout << endl << endl;
|
||||
} else
|
||||
cout << "队列未建立,请重新选择\n\n";
|
||||
file.close();
|
||||
}
|
||||
break;
|
||||
case 3://算法3.19 取链队的队头元素
|
||||
if (flag != -1 && flag != 0)
|
||||
cout << "队头元素为:\n" << GetHead(Q) << endl << endl;
|
||||
else
|
||||
cout << "队列中无元素,请重新选择\n" << endl;
|
||||
break;
|
||||
case 4://算法3.18 链队的出队
|
||||
cout << "依次弹出的队头元素为:\n";
|
||||
while (DeQueue(Q, e)) {
|
||||
flag = -1;
|
||||
cout << e << " ";
|
||||
}
|
||||
cout << endl << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
4
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.11-3.15/QNode.txt
Normal file
4
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.11-3.15/QNode.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
A
|
||||
B
|
||||
C
|
||||
D
|
||||
126
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.16-3.19/3.16-3.19.cpp
Normal file
126
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.16-3.19/3.16-3.19.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/***链队的基本操作***/
|
||||
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
using namespace std;
|
||||
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef char QElemType;
|
||||
typedef int Status;
|
||||
typedef char SElemType;
|
||||
|
||||
//- - - - - 队列的链式存储结构- - - - -
|
||||
typedef struct QNode {
|
||||
QElemType data;
|
||||
struct QNode *next;
|
||||
} QNode, *QueuePtr;
|
||||
typedef struct {
|
||||
QueuePtr front; //队头指针
|
||||
QueuePtr rear; //队尾指针
|
||||
} LinkQueue;
|
||||
|
||||
//算法3.16 链队的初始化
|
||||
Status InitQueue(LinkQueue &Q) {//构造一个空队列Q
|
||||
Q.front = Q.rear = new QNode; //生成新结点作为头结点,队头和队尾指针指向此结点
|
||||
Q.front->next = NULL; //头结点的指针域置空
|
||||
return OK;
|
||||
}
|
||||
|
||||
//算法3.17 链队的入队
|
||||
Status EnQueue(LinkQueue &Q, QElemType e) {//插入元素e为Q的新的队尾元素
|
||||
QueuePtr p;
|
||||
p = new QNode; //为入队元素分配结点空间,用指针p指向
|
||||
p->data = e; //将新结点数据域置为e
|
||||
p->next = NULL;
|
||||
Q.rear->next = p; //将新结点插入到队尾
|
||||
Q.rear = p; //修改队尾指针
|
||||
return OK;
|
||||
}
|
||||
|
||||
//算法3.18 链队的出队
|
||||
Status DeQueue(LinkQueue &Q, QElemType &e) {//删除Q的队头元素,用e返回其值
|
||||
QueuePtr p;
|
||||
if (Q.front == Q.rear)
|
||||
return ERROR; //若队列空,则返回ERROR
|
||||
p = Q.front->next; //p指向队头元素
|
||||
e = p->data; //e保存队头元素的值
|
||||
Q.front->next = p->next; //修改头指针
|
||||
if (Q.rear == p)
|
||||
Q.rear = Q.front; //最后一个元素被删,队尾指针指向头结点
|
||||
delete p; //释放原队头元素的空间
|
||||
return OK;
|
||||
}
|
||||
|
||||
//算法3.19 取链队的队头元素
|
||||
SElemType GetHead(LinkQueue Q) {//返回Q的队头元素,不修改队头指针
|
||||
if (Q.front != Q.rear) //队列非空
|
||||
return Q.front->next->data; //返回队头元素的值,队头指针不变
|
||||
}
|
||||
|
||||
int main() {
|
||||
int choose, flag = 0;
|
||||
LinkQueue Q;
|
||||
QElemType e, j;
|
||||
cout << "1.初始化\n";
|
||||
cout << "2.入队\n";
|
||||
cout << "3.读队头元素\n";
|
||||
cout << "4.出队\n";
|
||||
cout << "0.退出\n\n";
|
||||
|
||||
choose = -1;
|
||||
while (choose != 0) {
|
||||
cout << "请选择:";
|
||||
cin >> choose;
|
||||
switch (choose) {
|
||||
case 1://算法3.16 链队的初始化
|
||||
if (InitQueue(Q)) {
|
||||
flag = 1;
|
||||
cout << "成功对队列进行初始化\n\n";
|
||||
} else
|
||||
cout << "初始化队列失败\n\n";
|
||||
break;
|
||||
case 2: {//算法3.17 链队的入队
|
||||
fstream file;
|
||||
file.open("QNode.txt");
|
||||
if (!file) {
|
||||
cout << "错误!未找到文件!\n\n" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
if (flag) {
|
||||
flag = 1;
|
||||
cout << "入队的元素依次为:\n";
|
||||
while (!file.eof()) {
|
||||
file >> j;
|
||||
if (file.fail())
|
||||
break;
|
||||
else {
|
||||
EnQueue(Q, j);
|
||||
cout << j << " ";
|
||||
}
|
||||
}
|
||||
cout << endl << endl;
|
||||
} else
|
||||
cout << "队列未建立,请重新选择\n\n";
|
||||
file.close();
|
||||
}
|
||||
break;
|
||||
case 3://算法3.19 取链队的队头元素
|
||||
if (flag != -1 && flag != 0)
|
||||
cout << "队头元素为:\n" << GetHead(Q) << endl << endl;
|
||||
else
|
||||
cout << "队列中无元素,请重新选择\n" << endl;
|
||||
break;
|
||||
case 4://算法3.18 链队的出队
|
||||
cout << "依次弹出的队头元素为:\n";
|
||||
while (DeQueue(Q, e)) {
|
||||
flag = -1;
|
||||
cout << e << " ";
|
||||
}
|
||||
cout << endl << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
4
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.16-3.19/QNode.txt
Normal file
4
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.16-3.19/QNode.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
A
|
||||
B
|
||||
C
|
||||
D
|
||||
69
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.20/3.20.cpp
Normal file
69
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.20/3.20.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/***链栈实现数制的转换***/
|
||||
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
|
||||
typedef int Status;
|
||||
typedef struct SNode {
|
||||
int data;
|
||||
struct SNode *next;
|
||||
} SNode, *LinkStack;
|
||||
|
||||
Status InitStack(LinkStack &S) {
|
||||
S = NULL;
|
||||
return OK;
|
||||
}
|
||||
bool StackEmpty(LinkStack S) {
|
||||
if (!S)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
Status Push(LinkStack &S, int e) {
|
||||
LinkStack p;
|
||||
p = new SNode;
|
||||
if (!p) {
|
||||
return OVERFLOW;
|
||||
}
|
||||
p->data = e;
|
||||
p->next = S;
|
||||
S = p;
|
||||
return OK;
|
||||
}
|
||||
Status Pop(LinkStack &S, int &e) {
|
||||
LinkStack p;
|
||||
if (!S)
|
||||
return ERROR;
|
||||
e = S->data;
|
||||
p = S;
|
||||
S = S->next;
|
||||
delete p;
|
||||
return OK;
|
||||
}
|
||||
//算法3.20 数制的转换(链栈实现)
|
||||
void conversion(int N) {//对于任意一个非负十进制数,打印输出与其等值的八进制数
|
||||
int e;
|
||||
LinkStack S;
|
||||
InitStack(S); //初始化空栈S
|
||||
while (N) //当N非零时,循环
|
||||
{
|
||||
Push(S, N % 8); //把N与8求余得到的八进制数压入栈S
|
||||
N = N / 8; //N更新为N与8的商
|
||||
}
|
||||
while (!StackEmpty(S)) //当栈S非空时,循环
|
||||
{
|
||||
Pop(S, e); //弹出栈顶元素e
|
||||
cout << e; //输出e
|
||||
}
|
||||
}
|
||||
int main() {//对于输入的任意一个非负十进制数,打印输出与其等值的八进制数
|
||||
int n, e;
|
||||
cout << "输入一个非负十进制数:" << endl;
|
||||
cin >> n;
|
||||
|
||||
conversion(n);
|
||||
return 0;
|
||||
}
|
||||
96
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.21/3.21.cpp
Normal file
96
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.21/3.21.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/***链栈实现括号匹配***/
|
||||
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef char SElemType;
|
||||
typedef int Status;
|
||||
typedef struct SNode {
|
||||
int data;
|
||||
struct SNode *next;
|
||||
} SNode, *LinkStack;
|
||||
|
||||
Status InitStack(LinkStack &S) {
|
||||
S = NULL;
|
||||
return OK;
|
||||
}
|
||||
bool StackEmpty(LinkStack S) {
|
||||
if (!S)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
Status Push(LinkStack &S, SElemType e) {
|
||||
SNode *p = new SNode;
|
||||
if (!p) {
|
||||
return OVERFLOW;
|
||||
}
|
||||
p->data = e;
|
||||
p->next = S;
|
||||
S = p;
|
||||
return OK;
|
||||
}
|
||||
Status Pop(LinkStack &S, SElemType &e) {
|
||||
SNode *p;
|
||||
if (!S)
|
||||
return ERROR;
|
||||
e = S->data;
|
||||
p = S;
|
||||
S = S->next;
|
||||
delete p;
|
||||
return OK;
|
||||
}
|
||||
Status GetTop(LinkStack &S) {
|
||||
if (!S)
|
||||
return ERROR;
|
||||
return S->data;
|
||||
}
|
||||
|
||||
//算法3.21 括号的匹配
|
||||
Status Matching() {//检验表达式中所含括号是否正确匹配,如果匹配,则返回true,否则返回false
|
||||
//表达式以“#”结束
|
||||
char ch;
|
||||
SElemType x;
|
||||
LinkStack S;
|
||||
InitStack(S); //初始化空栈
|
||||
int flag = 1; //标记匹配结果以控制循环及返回结果
|
||||
cin >> ch; //读入第一个字符
|
||||
while (ch != '#' && flag) //假设表达式以“#”结尾
|
||||
{
|
||||
switch (ch) {
|
||||
case '[' :
|
||||
case '(': //若是左括号,则将其压入栈
|
||||
Push(S, ch);
|
||||
break;
|
||||
case ')': //若是“)”,则根据当前栈顶元素的值分情况考虑
|
||||
if (!StackEmpty(S) && GetTop(S) == '(')
|
||||
Pop(S, x); //若栈非空且栈顶元素是“(”,则正确匹配
|
||||
else
|
||||
flag = 0; //若栈空或栈顶元素不是“(”,则错误失败
|
||||
break;
|
||||
case ']': //若是“]”,则根据当前栈顶元素的值分情况考虑
|
||||
if (!StackEmpty(S) && GetTop(S) == '[')
|
||||
Pop(S, x); //若栈非空且栈顶元素是“[”,则正确匹配
|
||||
else
|
||||
flag = 0; //若栈空或栈顶元素不是“[”,则错误匹配
|
||||
break;
|
||||
} //switch
|
||||
cin >> ch; //继续读入下一个字符
|
||||
} //while
|
||||
if (StackEmpty(S) && flag)
|
||||
return true; //匹配成功
|
||||
else
|
||||
return false; //匹配失败
|
||||
}
|
||||
int main() {
|
||||
LinkStack S;
|
||||
cout << "请输入待匹配的表达式,以“#”结束:" << endl;
|
||||
int flag = (int) Matching();
|
||||
if (flag)
|
||||
cout << "括号匹配成功!" << endl;
|
||||
else
|
||||
cout << "括号匹配失败!" << endl;
|
||||
return 0;
|
||||
}
|
||||
29
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.22/3.22.cpp
Normal file
29
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.22/3.22.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include"3.22.h"
|
||||
|
||||
int menu() {
|
||||
int c;
|
||||
cout << "0-9以内的多项式计算" << endl;
|
||||
cout << "1.计算" << endl;
|
||||
cout << "0.退出\n" << endl;
|
||||
cout << "选择:";
|
||||
cin >> c;
|
||||
return c;
|
||||
}
|
||||
|
||||
void main() {
|
||||
while (1) {
|
||||
switch (menu()) {
|
||||
case 1: {
|
||||
cout << "请输入要计算的表达式(操作数和结果都在0-9的范围内,以#结束):" << endl;
|
||||
char res = EvaluateExpression();//算法3.22 表达式求值
|
||||
cout << "计算结果为" << res - 48 << endl << endl;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
cout << "退出成功\n" << endl;
|
||||
exit(0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
117
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.22/3.22.h
Normal file
117
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.22/3.22.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/***链栈实现表达式求值***/
|
||||
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
const char oper[7] = { '+', '-', '*', '/', '(', ')', '#' };
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef char SElemType;
|
||||
typedef int Status;
|
||||
typedef struct SNode {
|
||||
int data;
|
||||
struct SNode *next;
|
||||
} SNode, *LinkStack;
|
||||
|
||||
Status InitStack(LinkStack &S) {
|
||||
S = NULL;
|
||||
return OK;
|
||||
}
|
||||
bool StackEmpty(LinkStack S) {
|
||||
if (!S)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
Status Push(LinkStack &S, SElemType e) {
|
||||
SNode *p = new SNode;
|
||||
if (!p) {
|
||||
return OVERFLOW;
|
||||
}
|
||||
p->data = e;
|
||||
p->next = S;
|
||||
S = p;
|
||||
return OK;
|
||||
}
|
||||
Status Pop(LinkStack &S, SElemType &e) {
|
||||
SNode *p;
|
||||
if (!S)
|
||||
return ERROR;
|
||||
e = S->data;
|
||||
p = S;
|
||||
S = S->next;
|
||||
delete p;
|
||||
return OK;
|
||||
}
|
||||
Status GetTop(LinkStack &S) {
|
||||
if (!S)
|
||||
return ERROR;
|
||||
|
||||
return S->data;
|
||||
}
|
||||
bool In(char ch) {//判断ch是否为运算符
|
||||
for (int i = 0; i < 7; i++) {
|
||||
if (ch == oper[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
char Precede(char theta1, char theta2) {//判断运算符优先级
|
||||
if ((theta1 == '(' && theta2 == ')') || (theta1 == '#' && theta2 == '#')) {
|
||||
return '=';
|
||||
} else if (theta1 == '(' || theta1 == '#' || theta2 == '(' || (theta1
|
||||
== '+' || theta1 == '-') && (theta2 == '*' || theta2 == '/')) {
|
||||
return '<';
|
||||
} else
|
||||
return '>';
|
||||
}
|
||||
char Operate(char first, char theta, char second) {//计算两数运算结果
|
||||
switch (theta) {
|
||||
case '+':
|
||||
return (first - '0') + (second - '0') + 48;
|
||||
case '-':
|
||||
return (first - '0') - (second - '0') + 48;
|
||||
case '*':
|
||||
return (first - '0') * (second - '0') + 48;
|
||||
case '/':
|
||||
return (first - '0') / (second - '0') + 48;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//算法3.22 表达式求值
|
||||
char EvaluateExpression() {//算术表达式求值的算符优先算法,设OPTR和OPND分别为运算符栈和操作数栈
|
||||
LinkStack OPTR, OPND;
|
||||
char ch, theta, a, b, x, top;
|
||||
InitStack(OPND); //初始化OPND栈
|
||||
InitStack(OPTR); //初始化OPTR栈
|
||||
Push(OPTR, '#'); //将表达式起始符“#”压入OPTR栈
|
||||
cin >> ch;
|
||||
while (ch != '#' || (GetTop(OPTR) != '#')) //表达式没有扫描完毕或OPTR的栈顶元素不为“#”
|
||||
{
|
||||
if (!In(ch)) {
|
||||
Push(OPND, ch);
|
||||
cin >> ch;
|
||||
} //ch不是运算符则进OPND栈
|
||||
else
|
||||
switch (Precede(GetTop(OPTR), ch)) //比较OPTR的栈顶元素和ch的优先级
|
||||
{
|
||||
case '<':
|
||||
Push(OPTR, ch);
|
||||
cin >> ch; //当前字符ch压入OPTR栈,读入下一字符ch
|
||||
break;
|
||||
case '>':
|
||||
Pop(OPTR, theta); //弹出OPTR栈顶的运算符
|
||||
Pop(OPND, b);
|
||||
Pop(OPND, a); //弹出OPND栈顶的两个运算数
|
||||
Push(OPND, Operate(a, theta, b)); //将运算结果压入OPND栈
|
||||
break;
|
||||
case '=': //OPTR的栈顶元素是“(”且ch是“)”
|
||||
Pop(OPTR, x);
|
||||
cin >> ch; //弹出OPTR栈顶的“(”,读入下一字符ch
|
||||
break;
|
||||
} //switch
|
||||
} //while
|
||||
return GetTop(OPND); //OPND栈顶元素即为表达式求值结果
|
||||
}
|
||||
18
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.23/3.23.cpp
Normal file
18
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.23/3.23.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include"3.23.h"
|
||||
|
||||
Person dancer[MAXQSIZE];
|
||||
int main() {
|
||||
int i = 0;
|
||||
fstream file;
|
||||
file.open("DancePartner.txt");
|
||||
if (!file) {
|
||||
cout << "错误!未找到文件!\n\n" << endl;
|
||||
exit( ERROR);
|
||||
}
|
||||
while (!file.eof()) {
|
||||
file >> dancer[i].name >> dancer[i].sex;
|
||||
i++;
|
||||
}
|
||||
DancePartner(dancer, i + 1);
|
||||
return 0;
|
||||
}
|
||||
89
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.23/3.23.h
Normal file
89
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.23/3.23.h
Normal file
@@ -0,0 +1,89 @@
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<string>
|
||||
#define MAXQSIZE 100//队列可能达到的最大长度
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
using namespace std;
|
||||
|
||||
typedef struct {
|
||||
char name[20]; //姓名
|
||||
char sex; //性别,'F'表示女性,'M'表示男性
|
||||
} Person;
|
||||
|
||||
//- - - - - 队列的顺序存储结构- - - - -
|
||||
typedef struct {
|
||||
Person *base; //队列中数据元素类型为Person
|
||||
int front; //头指针
|
||||
int rear; //尾指针
|
||||
} SqQueue;
|
||||
|
||||
SqQueue Mdancers, Fdancers; //分别存放男士和女士入队者队列
|
||||
|
||||
int InitQueue(SqQueue &Q) {//构造一个空队列Q
|
||||
Q.base = new Person[MAXQSIZE]; //为队列分配一个最大容量为MAXSIZE的数组空间
|
||||
if (!Q.base)
|
||||
exit( OVERFLOW); //存储分配失败
|
||||
Q.front = Q.rear = 0; //头指针和尾指针置为零,队列为空
|
||||
return OK;
|
||||
}
|
||||
|
||||
int EnQueue(SqQueue &Q, Person e) {//插入元素e为Q的新的队尾元素
|
||||
if ((Q.rear + 1) % MAXQSIZE == Q.front) //尾指针在循环意义上加1后等于头指针,表明队满
|
||||
return ERROR;
|
||||
Q.base[Q.rear] = e; //新元素插入队尾
|
||||
Q.rear = (Q.rear + 1) % MAXQSIZE; //队尾指针加1
|
||||
return OK;
|
||||
}
|
||||
|
||||
int QueueEmpty(SqQueue &Q) {
|
||||
if (Q.front == Q.rear) //队空
|
||||
return OK;
|
||||
else
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
int DeQueue(SqQueue &Q, Person &e)//删除Q的队头元素,用e返回其值
|
||||
{
|
||||
if (Q.front == Q.rear)
|
||||
return ERROR; //队空
|
||||
e = Q.base[Q.front]; //保存队头元素
|
||||
Q.front = (Q.front + 1) % MAXQSIZE; //队头指针加1
|
||||
return OK;
|
||||
}
|
||||
|
||||
Person GetHead(SqQueue Q) {//返回Q的队头元素,不修改队头指针
|
||||
if (Q.front != Q.rear) //队列非空
|
||||
return Q.base[Q.front]; //返回队头元素的值,队头指针不变
|
||||
}
|
||||
|
||||
//算法3.23 舞伴问题
|
||||
void DancePartner(Person dancer[], int num) {//结构数组dancer中存放跳舞的男女,num是跳舞的人数。
|
||||
InitQueue(Mdancers); //男士队列初始化
|
||||
InitQueue(Fdancers); //女士队列初始化
|
||||
Person p;
|
||||
for (int i = 0; i < num; i++) //依次将跳舞者根据其性别入队
|
||||
{
|
||||
p = dancer[i];
|
||||
if (p.sex == 'F')
|
||||
EnQueue(Fdancers, p); //插入女队
|
||||
else
|
||||
EnQueue(Mdancers, p); //插入男队
|
||||
}
|
||||
cout << "The dancing partners are:" << endl;
|
||||
while (!QueueEmpty(Fdancers) && !QueueEmpty(Mdancers)) {//依次输出男女舞伴的姓名
|
||||
DeQueue(Fdancers, p); //女士出队
|
||||
cout << p.name << " "; //输出出队女士姓名
|
||||
DeQueue(Mdancers, p); //男士出队
|
||||
cout << p.name << endl; //输出出队男士姓名
|
||||
}
|
||||
if (!QueueEmpty(Fdancers)) { //女士队列非空,输出队头女士的姓名
|
||||
p = GetHead(Fdancers); //取女士队头
|
||||
cout << "The first man to get a partner is: " << endl;
|
||||
cout << p.name << endl;
|
||||
} else if (!QueueEmpty(Mdancers)) { //男士队列非空,输出队头男士的姓名
|
||||
p = GetHead(Mdancers); //取男士队头
|
||||
cout << "The first woman to get a partner is: " << p.name << endl;
|
||||
}
|
||||
}
|
||||
18
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.23/DancePartner.txt
Normal file
18
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.23/DancePartner.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
鄢雪棱 F
|
||||
高欣雅 F
|
||||
张甜源 F
|
||||
许丹丹 F
|
||||
冉小溪 F
|
||||
周如意 F
|
||||
胡思琪 F
|
||||
蒋雅琪 F
|
||||
金城武 M
|
||||
吴彦祖 M
|
||||
王思聪 M
|
||||
古天乐 M
|
||||
周杰伦 M
|
||||
李敏浩 M
|
||||
李钟硕 M
|
||||
马小云 M
|
||||
张智霖 M
|
||||
王力宏 M
|
||||
115
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.5-3.8/3.5-3.8.cpp
Normal file
115
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.5-3.8/3.5-3.8.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/***链栈的实现***/
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
using namespace std;
|
||||
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef int Status;
|
||||
typedef char SElemType;
|
||||
|
||||
typedef struct StackNode {
|
||||
SElemType data;
|
||||
struct StackNode *next;
|
||||
} StackNode, *LinkStack;
|
||||
|
||||
//算法3.5 链栈的初始化
|
||||
Status InitStack(LinkStack &S) { // 构造一个空栈 S,栈顶指针置空
|
||||
S = NULL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
//算法3.6 链栈的入栈
|
||||
Status Push(LinkStack &S, SElemType e) {//在栈顶插入元素e
|
||||
LinkStack p;
|
||||
p = new StackNode; //生成新结点
|
||||
p->data = e; //将新结点数据域置为e
|
||||
p->next = S; //将新结点插入栈顶
|
||||
S = p; //修改栈顶指针为p
|
||||
return OK;
|
||||
}
|
||||
|
||||
//算法3.7 链栈的出栈
|
||||
Status Pop(LinkStack &S, SElemType &e) {//删除S的栈顶元素,用e返回其值
|
||||
LinkStack p;
|
||||
if (S == NULL)
|
||||
return ERROR; //栈空
|
||||
e = S->data; //将栈顶元素赋给e
|
||||
p = S; //用p临时保存栈顶元素空间,以备释放
|
||||
S = S->next; //修改栈顶指针
|
||||
delete p; //释放原栈顶元素的空间
|
||||
return OK;
|
||||
}
|
||||
//算法3.8 取链栈的栈顶元素
|
||||
SElemType GetTop(LinkStack S) {//返回S的栈顶元素,不修改栈顶指针
|
||||
if (S != NULL) //栈非空
|
||||
return S->data; //返回栈顶元素的值,栈顶指针不变
|
||||
}
|
||||
|
||||
int main() {
|
||||
LinkStack s;
|
||||
int choose, flag = 0;
|
||||
SElemType j, t;
|
||||
cout << "1.初始化\n";
|
||||
cout << "2.入栈\n";
|
||||
cout << "3.读栈顶元素\n";
|
||||
cout << "4.出栈\n";
|
||||
cout << "0.退出\n\n";
|
||||
|
||||
choose = -1;
|
||||
while (choose != 0) {
|
||||
cout << "请选择:";
|
||||
cin >> choose;
|
||||
switch (choose) {
|
||||
case 1://算法3.5 链栈的初始化
|
||||
if (InitStack(s)) {
|
||||
flag = 1;
|
||||
cout << "成功对栈进行初始化\n\n";
|
||||
} else
|
||||
cout << "初始化栈失败\n\n";
|
||||
break;
|
||||
case 2: {//算法3.6 链栈的入栈
|
||||
fstream file;
|
||||
file.open("SqStack.txt");
|
||||
if (!file) {
|
||||
cout << "错误!未找到文件!\n\n" << endl;
|
||||
exit(ERROR);
|
||||
}
|
||||
if (flag) {
|
||||
flag = 1;
|
||||
cout << "进栈元素依次为:\n";
|
||||
while (!file.eof()) {
|
||||
file >> j;
|
||||
if (file.fail())
|
||||
break;
|
||||
else {
|
||||
Push(s, j);
|
||||
cout << j << " ";
|
||||
}
|
||||
}
|
||||
cout << endl << endl;
|
||||
} else
|
||||
cout << "栈未建立,请重新选择\n\n";
|
||||
file.close();
|
||||
}
|
||||
break;
|
||||
case 3://算法3.8 取链栈的栈顶元素
|
||||
if (flag != -1 && flag != 0)
|
||||
cout << "栈顶元素为:\n" << GetTop(s) << endl << endl;
|
||||
else
|
||||
cout << "栈中无元素,请重新选择\n" << endl;
|
||||
break;
|
||||
case 4://算法3.7 链栈的出栈
|
||||
if (flag) {
|
||||
cout << "依次弹出的栈顶元素为:\n";
|
||||
while (Pop(s, t))
|
||||
cout << t << " ";
|
||||
cout << endl << endl;
|
||||
} else
|
||||
cout << "栈未建立,请重新选择\n\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
4
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.5-3.8/SqStack.txt
Normal file
4
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.5-3.8/SqStack.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
A
|
||||
B
|
||||
C
|
||||
D
|
||||
53
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.9/3.9.cpp
Normal file
53
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第3章/3.9/3.9.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/***依次输出链表中的各个结点***/
|
||||
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef int Status;
|
||||
typedef char ElemType;
|
||||
typedef struct LNode {
|
||||
ElemType data; //结点的数据域
|
||||
LNode *next; //结点的指针域
|
||||
} LNode, *LinkList;//头指针
|
||||
|
||||
//后插法创建链表算法
|
||||
void CreateList_L(LinkList &L, int n) {
|
||||
L = new LNode;
|
||||
L->next = NULL;
|
||||
LNode *p, *r;
|
||||
r = L;
|
||||
for (int i = 0; i < n; i++) {
|
||||
p = new LNode;
|
||||
cin >> p->data;
|
||||
p->next = NULL;
|
||||
r->next = p;
|
||||
r = p;
|
||||
}
|
||||
}
|
||||
|
||||
//算法3.9 遍历输出链表中各个结点的递归算法
|
||||
void TraverseList(LinkList p) {
|
||||
if (p == NULL)
|
||||
return; //递归终止
|
||||
else {
|
||||
cout << p->data << endl; //输出当前结点的数据域
|
||||
TraverseList(p->next); //p指向后继指点继续递归
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n;
|
||||
LinkList L;
|
||||
//InitList(L);
|
||||
cout << "请输入元素个数:" << endl;
|
||||
cin >> n;
|
||||
cout << "请输入链表元素(以空格隔开,按回车结束):" << endl;
|
||||
CreateList_L(L, n); //后插法创建链表算法
|
||||
cout << "链表中的元素依次为:" << endl;
|
||||
TraverseList(L->next);
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
60
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第4章/4.1.cpp
Normal file
60
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第4章/4.1.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/***字符串匹配算法***/
|
||||
#include<cstring>
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef int Status;
|
||||
#define MAXSTRLEN 255 //用户可在255以内定义最长串长
|
||||
typedef char SString[MAXSTRLEN+1]; //0号单元存放串的长度
|
||||
|
||||
Status StrAssign(SString T, char *chars) { //生成一个其值等于chars的串T
|
||||
int i;
|
||||
if (strlen(chars) > MAXSTRLEN)
|
||||
return ERROR;
|
||||
else {
|
||||
T[0] = strlen(chars);
|
||||
for (i = 1; i <= T[0]; i++)
|
||||
T[i] = *(chars + i - 1);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
//算法4.1 BF算法
|
||||
int Index(SString S, SString T, int pos)
|
||||
{
|
||||
//返回模式T在主串S中第pos个字符之后第s一次出现的位置。若不存在,则返回值为0
|
||||
//其中,T非空,1≤pos≤StrLength(S)
|
||||
int i = pos;
|
||||
int j = 1;
|
||||
while(i <= S[0]&&j <= T[0])
|
||||
{
|
||||
if(S[i]==T[j])
|
||||
{
|
||||
++i;
|
||||
++j;
|
||||
} //继续比较后继字符
|
||||
else
|
||||
{
|
||||
i=i-j+2;
|
||||
j=1;
|
||||
} //指针后退重新开始匹配
|
||||
}
|
||||
if (j > T[0])
|
||||
return i - T[0];
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
}//Index
|
||||
|
||||
int main()
|
||||
{
|
||||
SString S;
|
||||
StrAssign(S,"bbaaabbaba") ;
|
||||
SString T;
|
||||
StrAssign(T,"abb") ;
|
||||
cout<<"主串和子串在第"<<Index(S,T,1)<<"个字符处首次匹配\n";
|
||||
return 0;
|
||||
}
|
||||
69
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第4章/4.2-4.3.cpp
Normal file
69
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第4章/4.2-4.3.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/***字符串匹配算法***/
|
||||
#include<cstring>
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef int Status;
|
||||
#define MAXSTRLEN 255 //用户可在255以内定义最长串长
|
||||
typedef char SString[MAXSTRLEN+1]; //0号单元存放串的长度
|
||||
|
||||
Status StrAssign(SString T, char *chars) { //生成一个其值等于chars的串T
|
||||
int i;
|
||||
if (strlen(chars) > MAXSTRLEN)
|
||||
return ERROR;
|
||||
else {
|
||||
T[0] = strlen(chars);
|
||||
for (i = 1; i <= T[0]; i++)
|
||||
T[i] = *(chars + i - 1);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
//算法4.3 计算next函数值
|
||||
void get_next(SString T, int next[])
|
||||
{ //求模式串T的next函数值并存入数组next
|
||||
int i = 1, j = 0;
|
||||
next[1] = 0;
|
||||
while (i < T[0])
|
||||
if (j == 0 || T[i] == T[j])
|
||||
{
|
||||
++i;
|
||||
++j;
|
||||
next[i] = j;
|
||||
}
|
||||
else
|
||||
j = next[j];
|
||||
}//get_next
|
||||
|
||||
//算法4.2 KMP算法
|
||||
int Index_KMP(SString S, SString T, int pos, int next[])
|
||||
{ // 利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算法
|
||||
//其中,T非空,1≤pos≤StrLength(S)
|
||||
int i = pos, j = 1;
|
||||
while (i <= S[0] && j <= T[0])
|
||||
if (j == 0 || S[i] == T[j]) // 继续比较后继字
|
||||
{
|
||||
++i;
|
||||
++j;
|
||||
}
|
||||
else
|
||||
j = next[j]; // 模式串向右移动
|
||||
if (j > T[0]) // 匹配成功
|
||||
return i - T[0];
|
||||
else
|
||||
return 0;
|
||||
}//Index_KMP
|
||||
|
||||
int main()
|
||||
{
|
||||
SString S;
|
||||
StrAssign(S,"aaabbaba") ;
|
||||
SString T;
|
||||
StrAssign(T,"abb") ;
|
||||
int *p = new int[T[0]+1]; // 生成T的next数组
|
||||
get_next(T,p);
|
||||
cout<<"主串和子串在第"<<Index_KMP(S,T,1,p)<<"个字符处首次匹配\n";
|
||||
return 0;
|
||||
}
|
||||
72
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第4章/4.4.cpp
Normal file
72
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第4章/4.4.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/***字符串匹配算法***/
|
||||
#include<cstring>
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
#define OVERFLOW -2
|
||||
typedef int Status;
|
||||
#define MAXSTRLEN 255 //用户可在255以内定义最长串长
|
||||
typedef char SString[MAXSTRLEN+1]; //0号单元存放串的长度
|
||||
|
||||
Status StrAssign(SString T, char *chars) { //生成一个其值等于chars的串T
|
||||
int i;
|
||||
if (strlen(chars) > MAXSTRLEN)
|
||||
return ERROR;
|
||||
else {
|
||||
T[0] = strlen(chars);
|
||||
for (i = 1; i <= T[0]; i++)
|
||||
T[i] = *(chars + i - 1);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
//算法4.4 计算next函数修正值
|
||||
void get_nextval(SString T, int nextval[])
|
||||
{ // 求模式串T的next函数修正值并存入数组nextval
|
||||
int i = 1, j = 0;
|
||||
nextval[1] = 0;
|
||||
while (i < T[0])
|
||||
if (j == 0 || T[i] == T[j])
|
||||
{
|
||||
++i;
|
||||
++j;
|
||||
if (T[i] != T[j])
|
||||
nextval[i] = j;
|
||||
else
|
||||
nextval[i] = nextval[j];
|
||||
} else
|
||||
j = nextval[j];
|
||||
}//get_nextval
|
||||
|
||||
//算法4.2 KMP算法
|
||||
int Index_KMP(SString S, SString T, int pos, int next[])
|
||||
{ // 利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算法
|
||||
//其中,T非空,1≤pos≤StrLength(S)
|
||||
int i = pos, j = 1;
|
||||
while (i <= S[0] && j <= T[0])
|
||||
if (j == 0 || S[i] == T[j]) // 继续比较后继字
|
||||
{
|
||||
++i;
|
||||
++j;
|
||||
}
|
||||
else
|
||||
j = next[j]; // 模式串向右移动
|
||||
if (j > T[0]) // 匹配成功
|
||||
return i - T[0];
|
||||
else
|
||||
return 0;
|
||||
}//Index_KMP
|
||||
|
||||
int main()
|
||||
{
|
||||
SString S;
|
||||
StrAssign(S,"babaaaabbaba") ;
|
||||
SString T;
|
||||
StrAssign(T,"abb") ;
|
||||
int *p = new int[T[0]+1]; // 生成T的next数组
|
||||
get_nextval(T,p);
|
||||
cout<<"主串和子串在第"<<Index_KMP(S,T,1,p)<<"个字符处首次匹配\n";
|
||||
return 0;
|
||||
}
|
||||
69
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第4章/4.5/1.cpp
Normal file
69
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第4章/4.5/1.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<string.h>
|
||||
using namespace std;
|
||||
|
||||
typedef struct{
|
||||
char ch[600]; //若是非空串,则按串长分配存储区,否则ch为NULL
|
||||
int len; //串长度
|
||||
}HString;
|
||||
|
||||
|
||||
int Index_BF(HString S,HString T,int pos)
|
||||
{//返回模式T在主串S中第pos个字符开始第一次出现的位置。若不存在,则返回值为0
|
||||
//其中,T非空,1≤pos≤StrLength(S)
|
||||
int i,j;
|
||||
i=pos; j=1;
|
||||
while(i<=S.len&&j<=T.len)
|
||||
{
|
||||
if(S.ch[i]==T.ch[j]){++i;++j;} //继续比较后继字符
|
||||
else{i=i-j+2;j=1;} //指针后退重新开始匹配
|
||||
}
|
||||
if(j>T.len) return i-T.len;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void Virus_detection()
|
||||
{
|
||||
int num,m,flag,i,j; char Vir[600];
|
||||
HString Virus,Person,temp;
|
||||
ifstream inFile("病毒感染检测输入数据.txt");
|
||||
ofstream outFile("病毒感染检测输出结果.txt");
|
||||
inFile>>num;//读取待检测的任务数
|
||||
while(num--) //依次检测每对病毒DNA和人的DNA是否匹配
|
||||
{
|
||||
inFile>>Virus.ch+1;//读取病毒DNA序列
|
||||
inFile>>Person.ch+1;//读取人的DNA序列
|
||||
strcpy(Vir,Virus.ch);
|
||||
Virus.len=strlen(Virus.ch)-1;
|
||||
Person.len=strlen(Person.ch)-1;
|
||||
flag=0;//用来标识是否匹配,初始为0,匹配后为非0
|
||||
m=Virus.len;
|
||||
for(i=m+1,j=1;j<=m;j++) Virus.ch[i++]=Virus.ch[j];
|
||||
//因病毒为环状,故将病毒的长度扩大2倍
|
||||
//即可线性取到所有长度为Virus.len的字符串
|
||||
Virus.ch[2*m+1]='\0'; //添加结束符号
|
||||
for(i=0;i<m;i++)
|
||||
{
|
||||
for(j=1;j<=m;j++) temp.ch[j]=Virus.ch[i+j];
|
||||
//取长为Virus.len的环形字符串
|
||||
//即Virus.ch[0]-- Virus.ch[Virus.len-1],
|
||||
//Virus.ch[1]-- Virus.ch[0], Virus.ch[2]-- Virus.ch[1]...
|
||||
temp.ch[m+1]='\0'; //添加结束符号
|
||||
temp.len=strlen(temp.ch)-1;
|
||||
flag=Index_BF(Person,temp,1); //模式匹配
|
||||
if(flag) break; //匹配即可退出循环
|
||||
}//for
|
||||
if(flag)
|
||||
outFile<<Vir+1<<" "<<Person.ch+1<<" "<<"YES"<<endl;
|
||||
else
|
||||
outFile<<Vir+1<<" "<<Person.ch+1<<" "<<"NO"<<endl;
|
||||
}//while
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Virus_detection();
|
||||
return 0;
|
||||
}
|
||||
|
||||
12
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第4章/4.5/病毒感染检测输入数据.txt
Normal file
12
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第4章/4.5/病毒感染检测输入数据.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
11
|
||||
baa bbaabbba
|
||||
baa aaabbbba
|
||||
aabb abceaabb
|
||||
aabb abaabcea
|
||||
abcd cdabbbab
|
||||
abcd cabbbbab
|
||||
abcde bcdedbda
|
||||
acc bdedbcda
|
||||
cde cdcdcdec
|
||||
cced cdccdcce
|
||||
bcd aabccdxdxbxa
|
||||
39
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.1.cpp
Normal file
39
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.1.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
//算法5.1 中序遍历的递归算法
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
typedef struct BiNode{ //二叉链表定义
|
||||
char data;
|
||||
struct BiNode *lchild,*rchild;
|
||||
}BiTNode,*BiTree;
|
||||
|
||||
//用算法5.3 先序遍历的顺序建立二叉链表
|
||||
void CreateBiTree(BiTree &T){
|
||||
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
|
||||
char ch;
|
||||
cin >> ch;
|
||||
if(ch=='#') T=NULL; //递归结束,建空树
|
||||
else{
|
||||
T=new BiTNode;
|
||||
T->data=ch; //生成根结点
|
||||
CreateBiTree(T->lchild); //递归创建左子树
|
||||
CreateBiTree(T->rchild); //递归创建右子树
|
||||
} //else
|
||||
} //CreateBiTree
|
||||
|
||||
void InOrderTraverse(BiTree T){
|
||||
//中序遍历二叉树T的递归算法
|
||||
if(T){
|
||||
InOrderTraverse(T->lchild);
|
||||
cout << T->data;
|
||||
InOrderTraverse(T->rchild);
|
||||
}
|
||||
}
|
||||
|
||||
void main(){
|
||||
BiTree tree;
|
||||
cout<<"请输入建立二叉链表的序列:\n";
|
||||
CreateBiTree(tree);
|
||||
cout<<"中序遍历的结果为:\n";
|
||||
InOrderTraverse(tree);
|
||||
cout<<endl;
|
||||
}
|
||||
69
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.10.cpp
Normal file
69
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.10.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
//算法5.10 构造赫夫曼树
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
typedef struct
|
||||
{
|
||||
int weight;
|
||||
int parent,lchild,rchild;
|
||||
}HTNode,*HuffmanTree;
|
||||
|
||||
void Select(HuffmanTree HT,int len,int &s1,int &s2)
|
||||
{
|
||||
int i,min1=0x3f3f3f3f,min2=0x3f3f3f3f;//先赋予最大值
|
||||
for(i=1;i<=len;i++)
|
||||
{
|
||||
if(HT[i].weight<min1&&HT[i].parent==0)
|
||||
{
|
||||
min1=HT[i].weight;
|
||||
s1=i;
|
||||
}
|
||||
}
|
||||
int temp=HT[s1].weight;//将原值存放起来,然后先赋予最大值,防止s1被重复选择
|
||||
HT[s1].weight=0x3f3f3f3f;
|
||||
for(i=1;i<=len;i++)
|
||||
{
|
||||
if(HT[i].weight<min2&&HT[i].parent==0)
|
||||
{
|
||||
min2=HT[i].weight;
|
||||
s2=i;
|
||||
}
|
||||
}
|
||||
HT[s1].weight=temp;//恢复原来的值
|
||||
}
|
||||
|
||||
void CreatHuffmanTree(HuffmanTree &HT,int n)
|
||||
{
|
||||
//构造赫夫曼树HT
|
||||
int m,s1,s2,i;
|
||||
if(n<=1) return;
|
||||
m=2*n-1;
|
||||
HT=new HTNode[m+1]; //0号单元未用,所以需要动态分配m+1个单元,HT[m]表示根结点
|
||||
for(i=1;i<=m;++i) //将1~m号单元中的双亲、左孩子,右孩子的下标都初始化为0
|
||||
{ HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; }
|
||||
cout<<"请输入叶子结点的权值:\n";
|
||||
for(i=1;i<=n;++i) //输入前n个单元中叶子结点的权值
|
||||
cin>>HT[i].weight;
|
||||
/*――――――――――初始化工作结束,下面开始创建赫夫曼树――――――――――*/
|
||||
for(i=n+1;i<=m;++i)
|
||||
{ //通过n-1次的选择、删除、合并来创建赫夫曼树
|
||||
Select(HT,i-1,s1,s2);
|
||||
//在HT[k](1≤k≤i-1)中选择两个其双亲域为0且权值最小的结点,
|
||||
// 并返回它们在HT中的序号s1和s2
|
||||
HT[s1].parent=i;
|
||||
HT[s2].parent=i;
|
||||
//得到新结点i,从森林中删除s1,s2,将s1和s2的双亲域由0改为i
|
||||
HT[i].lchild=s1;
|
||||
HT[i].rchild=s2 ; //s1,s2分别作为i的左右孩子
|
||||
HT[i].weight=HT[s1].weight+HT[s2].weight; //i 的权值为左右孩子权值之和
|
||||
} //for
|
||||
} // CreatHuffmanTree
|
||||
|
||||
void main()
|
||||
{
|
||||
HuffmanTree HT;
|
||||
int n;
|
||||
cout<<"请输入叶子结点的个数:\n";
|
||||
cin>>n;
|
||||
CreatHuffmanTree(HT,n);
|
||||
cout<<"哈夫曼树建立完毕!\n";
|
||||
}
|
||||
105
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.11.cpp
Normal file
105
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.11.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
//算法5.11 根据赫夫曼树求赫夫曼编码
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
typedef struct
|
||||
{
|
||||
int weight;
|
||||
int parent,lchild,rchild;
|
||||
}HTNode,*HuffmanTree;
|
||||
typedef char **HuffmanCode;
|
||||
|
||||
void Select(HuffmanTree HT,int len,int &s1,int &s2)
|
||||
{
|
||||
int i,min1=0x3f3f3f3f,min2=0x3f3f3f3f;//先赋予最大值
|
||||
for(i=1;i<=len;i++)
|
||||
{
|
||||
if(HT[i].weight<min1&&HT[i].parent==0)
|
||||
{
|
||||
min1=HT[i].weight;
|
||||
s1=i;
|
||||
}
|
||||
}
|
||||
int temp=HT[s1].weight;//将原值存放起来,然后先赋予最大值,防止s1被重复选择
|
||||
HT[s1].weight=0x3f3f3f3f;
|
||||
for(i=1;i<=len;i++)
|
||||
{
|
||||
if(HT[i].weight<min2&&HT[i].parent==0)
|
||||
{
|
||||
min2=HT[i].weight;
|
||||
s2=i;
|
||||
}
|
||||
}
|
||||
HT[s1].weight=temp;//恢复原来的值
|
||||
}
|
||||
|
||||
//用算法5.10构造赫夫曼树
|
||||
void CreatHuffmanTree(HuffmanTree &HT,int n)
|
||||
{
|
||||
//构造赫夫曼树HT
|
||||
int m,s1,s2,i;
|
||||
if(n<=1) return;
|
||||
m=2*n-1;
|
||||
HT=new HTNode[m+1]; //0号单元未用,所以需要动态分配m+1个单元,HT[m]表示根结点
|
||||
for(i=1;i<=m;++i) //将1~m号单元中的双亲、左孩子,右孩子的下标都初始化为0
|
||||
{ HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; }
|
||||
cout<<"请输入叶子结点的权值:\n";
|
||||
for(i=1;i<=n;++i) //输入前n个单元中叶子结点的权值
|
||||
cin>>HT[i].weight;
|
||||
/*――――――――――初始化工作结束,下面开始创建赫夫曼树――――――――――*/
|
||||
for(i=n+1;i<=m;++i)
|
||||
{ //通过n-1次的选择、删除、合并来创建赫夫曼树
|
||||
Select(HT,i-1,s1,s2);
|
||||
//在HT[k](1≤k≤i-1)中选择两个其双亲域为0且权值最小的结点,
|
||||
// 并返回它们在HT中的序号s1和s2
|
||||
HT[s1].parent=i;
|
||||
HT[s2].parent=i;
|
||||
//得到新结点i,从森林中删除s1,s2,将s1和s2的双亲域由0改为i
|
||||
HT[i].lchild=s1;
|
||||
HT[i].rchild=s2 ; //s1,s2分别作为i的左右孩子
|
||||
HT[i].weight=HT[s1].weight+HT[s2].weight; //i 的权值为左右孩子权值之和
|
||||
} //for
|
||||
}
|
||||
// CreatHuffmanTree
|
||||
void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
|
||||
{
|
||||
//从叶子到根逆向求每个字符的赫夫曼编码,存储在编码表HC中
|
||||
int i,start,c,f;
|
||||
HC=new char*[n+1]; //分配n个字符编码的头指针矢量
|
||||
char *cd=new char[n]; //分配临时存放编码的动态数组空间
|
||||
cd[n-1]='\0'; //编码结束符
|
||||
for(i=1;i<=n;++i)
|
||||
{ //逐个字符求赫夫曼编码
|
||||
start=n-1; //start开始时指向最后,即编码结束符位置
|
||||
c=i;
|
||||
f=HT[i].parent; //f指向结点c的双亲结点
|
||||
while(f!=0)
|
||||
{ //从叶子结点开始向上回溯,直到根结点
|
||||
--start; //回溯一次start向前指一个位置
|
||||
if(HT[f].lchild==c)
|
||||
cd[start]='0'; //结点c是f的左孩子,则生成代码0
|
||||
else
|
||||
cd[start]='1'; //结点c是f的右孩子,则生成代码1
|
||||
c=f;
|
||||
f=HT[f].parent; //继续向上回溯
|
||||
} //求出第i个字符的编码
|
||||
HC[i]=new char[n-start]; // 为第i 个字符编码分配空间
|
||||
strcpy(HC[i], &cd[start]); //将求得的编码从临时空间cd复制到HC的当前行中
|
||||
}
|
||||
delete cd; //释放临时空间
|
||||
} // CreatHuffanCode
|
||||
void show(HuffmanTree HT,HuffmanCode HC)
|
||||
{
|
||||
for(int i=1;i<=sizeof(HC)+1;i++)
|
||||
cout<<HT[i].weight<<"编码为"<<HC[i]<<endl;
|
||||
}
|
||||
void main()
|
||||
{
|
||||
HuffmanTree HT;
|
||||
HuffmanCode HC;
|
||||
int n;
|
||||
cout<<"请输入叶子结点的个数:\n";
|
||||
cin>>n; //输入赫夫曼树的叶子结点个数
|
||||
CreatHuffmanTree(HT,n);
|
||||
CreatHuffmanCode(HT,HC,n);
|
||||
show(HT,HC);
|
||||
}
|
||||
201
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.12-5.13.cpp
Normal file
201
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.12-5.13.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
#define ERROR -1
|
||||
#define MAXSIZE 100
|
||||
using namespace std;
|
||||
|
||||
typedef struct BiTNode{ //二叉树的二叉链表存储表示
|
||||
char data;
|
||||
struct BiTNode *lchild,*rchild;
|
||||
}BiTNode,*BiTree;
|
||||
|
||||
typedef struct{ // 字符栈定义
|
||||
char *base;
|
||||
char *top;
|
||||
int stacksize;
|
||||
}SqStack;
|
||||
|
||||
typedef struct{ //树栈定义
|
||||
BiTree *base;
|
||||
BiTree *top;
|
||||
int stacksize;
|
||||
}BiTreeStack;
|
||||
|
||||
|
||||
void InitStack(SqStack &S){ //字符栈初始化
|
||||
S.base=new char[MAXSIZE];
|
||||
if(!S.base) exit(-1);
|
||||
S.top=S.base;
|
||||
S.stacksize=MAXSIZE;
|
||||
}
|
||||
|
||||
|
||||
void InitBiTreeStack(BiTreeStack &S){ //树栈初始化
|
||||
S.base=new BiTree[MAXSIZE];
|
||||
if(!S.base) exit(-1);
|
||||
S.top=S.base;
|
||||
S.stacksize=MAXSIZE;
|
||||
}
|
||||
|
||||
|
||||
void Push(SqStack &S,char e) //字符栈入栈
|
||||
{
|
||||
if(S.top-S.base==S.stacksize) return ;
|
||||
*S.top=e;
|
||||
S.top++;
|
||||
|
||||
}
|
||||
void PushBiTree(BiTreeStack &S,BiTree e) //树栈入栈
|
||||
{
|
||||
if(S.top-S.base==S.stacksize) return ;
|
||||
*S.top=e;
|
||||
S.top++;
|
||||
|
||||
}
|
||||
void Pop(SqStack &S,char &e) //字符栈出栈
|
||||
{
|
||||
if(S.top==S.base) return;
|
||||
e=*--S.top;
|
||||
|
||||
}
|
||||
|
||||
void PopBiTree(BiTreeStack &S,BiTree &e) //树栈出栈
|
||||
{
|
||||
if(S.top==S.base) return;
|
||||
e=*--S.top;
|
||||
|
||||
}
|
||||
|
||||
|
||||
char GetTop(SqStack &S) //字符栈得到栈顶函数
|
||||
{
|
||||
if(S.top==S.base) exit(1);
|
||||
return *(S.top-1);
|
||||
}
|
||||
|
||||
char Precede(char t1,char t2)
|
||||
{ /* 根据教科书表3.1,判断两符号的优先关系 */
|
||||
char f;
|
||||
switch(t2)
|
||||
{
|
||||
case '+':if(t1=='('||t1=='#')
|
||||
f='<';
|
||||
else
|
||||
f='>';
|
||||
break;
|
||||
case '-':if(t1=='('||t1=='#')
|
||||
f='<';
|
||||
else
|
||||
f='>';
|
||||
break;
|
||||
case '*':if(t1=='*'||t1=='/'||t1==')')
|
||||
f='>';
|
||||
else
|
||||
f='<';
|
||||
break;
|
||||
case '/':if(t1=='*'||t1=='/'||t1==')')
|
||||
f='>';
|
||||
else
|
||||
f='<';
|
||||
break;
|
||||
case '(':if(t1!=')')
|
||||
f='<';
|
||||
break;
|
||||
case')':if(t1=='(')
|
||||
f='=';
|
||||
else
|
||||
f='>';
|
||||
break;
|
||||
case'#':if(t1=='#')
|
||||
f='=';
|
||||
else
|
||||
f='>';
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
int In(char c)
|
||||
{ /* 判断c是否为运算符 */
|
||||
switch(c)
|
||||
{
|
||||
case '+':
|
||||
case'-':
|
||||
case'*':
|
||||
case '/':
|
||||
case'#':
|
||||
case '(':
|
||||
case')':return 1;break;
|
||||
default:return 0;
|
||||
}
|
||||
}
|
||||
int GetValue(char theta,int a,int b) //进行运算的函数
|
||||
{
|
||||
int c;
|
||||
switch(theta)
|
||||
{
|
||||
case '+':c=a+b;break;
|
||||
case'-':c=a-b;break;
|
||||
case'*':c=a*b;break;
|
||||
case'/':c=a/b;break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void CreateExpTree(BiTree &T,BiTree a,BiTree b,char ch){ //简单二叉树的创建
|
||||
T=new BiTNode;
|
||||
T->data=ch;
|
||||
T->lchild=a;
|
||||
T->rchild=b;
|
||||
}
|
||||
|
||||
|
||||
void InitExpTree(BiTree &T) //算法5.12 表达式树的创建
|
||||
{
|
||||
SqStack OPTR;
|
||||
BiTreeStack EXPT;
|
||||
char ch,theta,x;
|
||||
BiTree a,b;
|
||||
InitStack(OPTR);Push(OPTR,'#');
|
||||
InitBiTreeStack(EXPT);cin>>ch;
|
||||
while(ch!='#'||GetTop(OPTR)!='#'){
|
||||
if(!In(ch)){CreateExpTree(T,NULL,NULL,ch);PushBiTree(EXPT,T);cin>>ch;}//*q
|
||||
else
|
||||
switch(Precede(GetTop(OPTR),ch)){
|
||||
case'<':
|
||||
Push(OPTR,ch);cin>>ch;
|
||||
break;
|
||||
case'>':
|
||||
Pop(OPTR,theta);
|
||||
PopBiTree(EXPT,b);PopBiTree(EXPT,a);
|
||||
CreateExpTree(T,a,b,theta); //*
|
||||
PushBiTree(EXPT,T);
|
||||
break;
|
||||
case'=':
|
||||
Pop(OPTR,x);cin>>ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int EvaluateExTree(BiTree T){ //算法5.13 表达式树的求值
|
||||
int lvalue,rvalue;
|
||||
lvalue=rvalue=0;
|
||||
if(T->lchild==NULL&&T->rchild==NULL)
|
||||
return T->data-'0';
|
||||
else{
|
||||
lvalue=EvaluateExTree(T->lchild);
|
||||
rvalue=EvaluateExTree(T->rchild);
|
||||
return GetValue(T->data,lvalue,rvalue); //运算函数
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
cout<<"请输入算术表达式,并以#结束,中间计算过程要是个位数."<<endl;
|
||||
BiTree T;
|
||||
InitExpTree(T); //创建表达式树
|
||||
cout<<EvaluateExTree(T)<<endl; //输出值
|
||||
}
|
||||
|
||||
97
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.2.cpp
Normal file
97
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.2.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
//算法5.2 中序遍历的非递归算法
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
//二叉树的二叉链表存储表示
|
||||
typedef struct BiNode
|
||||
{
|
||||
char data; //结点数据域
|
||||
struct BiNode *lchild,*rchild; //左右孩子指针
|
||||
}BiTNode,*BiTree;
|
||||
|
||||
//链栈的定义
|
||||
typedef struct StackNode
|
||||
{
|
||||
BiTNode data;
|
||||
struct StackNode *next;
|
||||
}StackNode,*LinkStack;
|
||||
|
||||
//用算法5.3 先序遍历的顺序建立二叉链表
|
||||
void CreateBiTree(BiTree &T)
|
||||
{
|
||||
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
|
||||
char ch;
|
||||
cin >> ch;
|
||||
if(ch=='#') T=NULL; //递归结束,建空树
|
||||
else{
|
||||
T=new BiTNode;
|
||||
T->data=ch; //生成根结点
|
||||
CreateBiTree(T->lchild); //递归创建左子树
|
||||
CreateBiTree(T->rchild); //递归创建右子树
|
||||
} //else
|
||||
} //CreateBiTree
|
||||
|
||||
void InitStack(LinkStack &S)
|
||||
{
|
||||
//构造一个空栈S,栈顶指针置空
|
||||
S=NULL;
|
||||
}
|
||||
|
||||
bool StackEmpty(LinkStack S)
|
||||
{
|
||||
if(!S)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Push(LinkStack &S,BiTree e)
|
||||
{
|
||||
//在栈顶插入元素*e
|
||||
StackNode *p=new StackNode;
|
||||
p->data=*e;
|
||||
p->next=S;
|
||||
S=p;
|
||||
}
|
||||
|
||||
void Pop(LinkStack &S,BiTree e)
|
||||
{
|
||||
if(S!=NULL)//原书上写的是if(S==NULL)return ERROR;
|
||||
{
|
||||
*e=S->data;
|
||||
StackNode *p=S;
|
||||
S=S->next;
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
void InOrderTraverse1(BiTree T)
|
||||
{
|
||||
// 中序遍历二叉树T的非递归算法
|
||||
LinkStack S; BiTree p;
|
||||
BiTree q=new BiTNode;
|
||||
InitStack(S); p=T;
|
||||
while(p||!StackEmpty(S))
|
||||
{
|
||||
if(p)
|
||||
{
|
||||
Push(S,p); //p非空根指针进栈,遍历左子树
|
||||
p=p->lchild;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pop(S,q); //p为空根指针退栈,访问根结点,遍历右子树
|
||||
cout<<q->data;
|
||||
p=q->rchild;
|
||||
}
|
||||
} // while
|
||||
} // InOrderTraverse
|
||||
|
||||
void main()
|
||||
{
|
||||
BiTree tree;
|
||||
cout<<"请输入建立二叉链表的序列:\n";
|
||||
CreateBiTree(tree);
|
||||
cout<<"中序遍历的结果为:\n";
|
||||
InOrderTraverse1(tree);
|
||||
cout<<endl;
|
||||
}
|
||||
44
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.3.cpp
Normal file
44
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.3.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
//算法5.3 先序遍历的的顺序建立二叉链表
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
//二叉树的二叉链表存储表示
|
||||
typedef struct BiNode
|
||||
{
|
||||
char data; //结点数据域
|
||||
struct BiNode *lchild,*rchild; //左右孩子指针
|
||||
}BiTNode,*BiTree;
|
||||
|
||||
void CreateBiTree(BiTree &T)
|
||||
{
|
||||
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
|
||||
char ch;
|
||||
cin >> ch;
|
||||
if(ch=='#') T=NULL; //递归结束,建空树
|
||||
else{
|
||||
T=new BiTNode;
|
||||
T->data=ch; //生成根结点
|
||||
CreateBiTree(T->lchild); //递归创建左子树
|
||||
CreateBiTree(T->rchild); //递归创建右子树
|
||||
} //else
|
||||
} //CreateBiTree
|
||||
|
||||
//用算法5.1 中序遍历的递归算法
|
||||
void InOrderTraverse(BiTree T)
|
||||
{
|
||||
//中序遍历二叉树T的递归算法
|
||||
if(T){
|
||||
InOrderTraverse(T->lchild);
|
||||
cout << T->data;
|
||||
InOrderTraverse(T->rchild);
|
||||
}
|
||||
}
|
||||
void main()
|
||||
{
|
||||
BiTree tree;
|
||||
cout<<"请输入建立二叉链表的序列:\n";
|
||||
CreateBiTree(tree);
|
||||
cout<<"所建立的二叉链表中序序列:\n";
|
||||
InOrderTraverse(tree);
|
||||
cout<<endl;
|
||||
}
|
||||
62
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.4.cpp
Normal file
62
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.4.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
//算法5.4 复制二叉树
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
//二叉树的二叉链表存储表示
|
||||
typedef struct BiNode
|
||||
{
|
||||
char data; //结点数据域
|
||||
struct BiNode *lchild,*rchild; //左右孩子指针
|
||||
}BiTNode,*BiTree;
|
||||
|
||||
//用算法5.3建立二叉链表
|
||||
void CreateBiTree(BiTree &T)
|
||||
{
|
||||
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
|
||||
char ch;
|
||||
cin >> ch;
|
||||
if(ch=='#') T=NULL; //递归结束,建空树
|
||||
else{
|
||||
T=new BiTNode;
|
||||
T->data=ch; //生成根结点
|
||||
CreateBiTree(T->lchild); //递归创建左子树
|
||||
CreateBiTree(T->rchild); //递归创建右子树
|
||||
} //else
|
||||
} //CreateBiTree
|
||||
|
||||
void Copy(BiTree T, BiTree &NewT)
|
||||
{
|
||||
if(T==NULL )
|
||||
{ //如果是空树,递归结束
|
||||
NewT=NULL;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewT=new BiTNode;
|
||||
NewT->data= T->data; //复制根结点
|
||||
Copy(T->lchild, NewT->lchild); //递归复制左子树
|
||||
Copy(T->rchild, NewT->rchild); //递归复制右子树
|
||||
} //else
|
||||
} //CopyBiTree
|
||||
|
||||
//用算法5.1 中序遍历的递归算法
|
||||
void InOrderTraverse(BiTree T)
|
||||
{
|
||||
//中序遍历二叉树T的递归算法
|
||||
if(T){
|
||||
InOrderTraverse(T->lchild);
|
||||
cout << T->data;
|
||||
InOrderTraverse(T->rchild);
|
||||
}
|
||||
}
|
||||
void main()
|
||||
{
|
||||
BiTree tree,new_tree;
|
||||
cout<<"请输入建立二叉树的序列:\n";
|
||||
CreateBiTree(tree);
|
||||
Copy(tree,new_tree);
|
||||
cout<<"复制得到的新树的中序序列:\n";
|
||||
InOrderTraverse(new_tree);
|
||||
cout<<endl;
|
||||
}
|
||||
47
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.5.cpp
Normal file
47
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.5.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
//算法5.5 计算二叉树的深度
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
//二叉树的二叉链表存储表示
|
||||
typedef struct BiNode
|
||||
{
|
||||
char data; //结点数据域
|
||||
struct BiNode *lchild,*rchild; //左右孩子指针
|
||||
}BiTNode,*BiTree;
|
||||
|
||||
//用算法5.3建立二叉链表
|
||||
void CreateBiTree(BiTree &T)
|
||||
{
|
||||
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
|
||||
char ch;
|
||||
cin >> ch;
|
||||
if(ch=='#') T=NULL; //递归结束,建空树
|
||||
else{
|
||||
T=new BiTNode;
|
||||
T->data=ch; //生成根结点
|
||||
CreateBiTree(T->lchild); //递归创建左子树
|
||||
CreateBiTree(T->rchild); //递归创建右子树
|
||||
} //else
|
||||
} //CreateBiTree
|
||||
|
||||
int Depth(BiTree T)
|
||||
{
|
||||
int m,n;
|
||||
if(T == NULL ) return 0; //如果是空树,深度为0,递归结束
|
||||
else
|
||||
{
|
||||
m=Depth(T->lchild); //递归计算左子树的深度记为m
|
||||
n=Depth(T->rchild); //递归计算右子树的深度记为n
|
||||
if(m>n) return(m+1); //二叉树的深度为m 与n的较大者加1
|
||||
else return (n+1);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
BiTree tree;
|
||||
cout<<"请输入建立二叉链表的序列:\n";
|
||||
CreateBiTree(tree);
|
||||
cout<<"数的深度为:"<<Depth(tree)<<endl;
|
||||
|
||||
}
|
||||
41
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.6.cpp
Normal file
41
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.6.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
//算法5.6 统计二叉树中结点的个数
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
//二叉树的二叉链表存储表示
|
||||
typedef struct BiNode
|
||||
{
|
||||
char data; //结点数据域
|
||||
struct BiNode *lchild,*rchild; //左右孩子指针
|
||||
}BiTNode,*BiTree;
|
||||
|
||||
//用算法5.3建立二叉链表
|
||||
void CreateBiTree(BiTree &T)
|
||||
{
|
||||
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
|
||||
char ch;
|
||||
cin >> ch;
|
||||
if(ch=='#') T=NULL; //递归结束,建空树
|
||||
else{
|
||||
T=new BiTNode;
|
||||
T->data=ch; //生成根结点
|
||||
CreateBiTree(T->lchild); //递归创建左子树
|
||||
CreateBiTree(T->rchild); //递归创建右子树
|
||||
} //else
|
||||
} //CreateBiTree
|
||||
|
||||
int NodeCount(BiTree T)
|
||||
{
|
||||
if(T==NULL) return 0; // 如果是空树,则结点个数为0,递归结束
|
||||
else return NodeCount(T->lchild)+ NodeCount(T->rchild) +1;
|
||||
//否则结点个数为左子树的结点个数+右子树的结点个数+1
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
BiTree tree;
|
||||
cout<<"请输入建立二叉链表的序列:\n";
|
||||
CreateBiTree(tree);
|
||||
cout<<"结点个数为:"<<NodeCount(tree)<<endl;
|
||||
|
||||
}
|
||||
66
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.7.cpp
Normal file
66
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.7.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
//算法5.7 以结点P为根的子树中序线索化
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
//二叉树的二叉线索类型存储表示
|
||||
typedef struct BiThrNode
|
||||
{
|
||||
char data; //结点数据域
|
||||
struct BiThrNode *lchild,*rchild; //左右孩子指针
|
||||
int LTag,RTag;
|
||||
}BiThrNode,*BiThrTree;
|
||||
|
||||
//全局变量pre
|
||||
BiThrNode *pre=new BiThrNode;
|
||||
|
||||
//用算法5.3建立二叉链表
|
||||
void CreateBiTree(BiThrTree &T)
|
||||
{
|
||||
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
|
||||
char ch;
|
||||
cin >> ch;
|
||||
if(ch=='#') T=NULL; //递归结束,建空树
|
||||
else
|
||||
{
|
||||
T=new BiThrNode;
|
||||
T->data=ch; //生成根结点
|
||||
CreateBiTree(T->lchild); //递归创建左子树
|
||||
CreateBiTree(T->rchild); //递归创建右子树
|
||||
} //else
|
||||
} //CreateBiTree
|
||||
|
||||
void InThreading(BiThrTree p)
|
||||
{
|
||||
//pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索
|
||||
if(p)
|
||||
{
|
||||
InThreading(p->lchild); //左子树递归线索化
|
||||
if(!p->lchild)
|
||||
{ //p的左孩子为空
|
||||
p->LTag=1; //给p加上左线索
|
||||
p->lchild=pre; //p的左孩子指针指向pre(前驱)
|
||||
}
|
||||
else
|
||||
p->LTag=0;
|
||||
if(!pre->rchild)
|
||||
{ //pre的右孩子为空
|
||||
pre->RTag=1; //给pre加上右线索
|
||||
pre->rchild=p; //pre的右孩子指针指向p(后继)
|
||||
}
|
||||
else
|
||||
pre->RTag=0;
|
||||
pre=p; //保持pre指向p的前驱
|
||||
InThreading(p->rchild); //右子树递归线索化
|
||||
}
|
||||
}//InThreading
|
||||
|
||||
void main()
|
||||
{
|
||||
pre->RTag=1;
|
||||
pre->rchild=NULL;
|
||||
BiThrTree tree;
|
||||
cout<<"请输入建立二叉链表的序列:\n";
|
||||
CreateBiTree(tree);
|
||||
InThreading(tree);
|
||||
cout<<"线索化完毕!\n";
|
||||
}
|
||||
85
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.8.cpp
Normal file
85
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.8.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
//算法5.8 带头结点的中序线索化
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
//二叉树的二叉线索类型存储表示
|
||||
typedef struct BiThrNode
|
||||
{
|
||||
char data; //结点数据域
|
||||
struct BiThrNode *lchild,*rchild; //左右孩子指针
|
||||
int LTag,RTag;
|
||||
}BiThrNode,*BiThrTree;
|
||||
|
||||
//全局变量pre
|
||||
BiThrNode *pre=new BiThrNode;
|
||||
|
||||
//用算法5.3建立二叉链表
|
||||
void CreateBiTree(BiThrTree &T)
|
||||
{
|
||||
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
|
||||
char ch;
|
||||
cin >> ch;
|
||||
if(ch=='#') T=NULL; //递归结束,建空树
|
||||
else
|
||||
{
|
||||
T=new BiThrNode;
|
||||
T->data=ch; //生成根结点
|
||||
CreateBiTree(T->lchild); //递归创建左子树
|
||||
CreateBiTree(T->rchild); //递归创建右子树
|
||||
} //else
|
||||
} //CreateBiTree
|
||||
|
||||
//用算法5.7 以结点P为根的子树中序线索化
|
||||
void InThreading(BiThrTree p)
|
||||
{
|
||||
//pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索
|
||||
if(p)
|
||||
{
|
||||
InThreading(p->lchild); //左子树递归线索化
|
||||
if(!p->lchild)
|
||||
{ //p的左孩子为空
|
||||
p->LTag=1; //给p加上左线索
|
||||
p->lchild=pre; //p的左孩子指针指向pre(前驱)
|
||||
}
|
||||
else
|
||||
p->LTag=0;
|
||||
if(!pre->rchild)
|
||||
{ //pre的右孩子为空
|
||||
pre->RTag=1; //给pre加上右线索
|
||||
pre->rchild=p; //pre的右孩子指针指向p(后继)
|
||||
}
|
||||
else
|
||||
pre->RTag=0;
|
||||
pre=p; //保持pre指向p的前驱
|
||||
InThreading(p->rchild); //右子树递归线索化
|
||||
}
|
||||
}//InThreading
|
||||
|
||||
void InOrderThreading (BiThrTree &Thrt,BiThrTree T)
|
||||
{
|
||||
//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
|
||||
Thrt=new BiThrNode; //建头结点
|
||||
Thrt->LTag=0; //头结点有左孩子,若树非空,则其左孩子为树根
|
||||
Thrt->RTag=1; //头结点的右孩子指针为右线索
|
||||
Thrt->rchild=Thrt; //初始化时右指针指向自己
|
||||
if(!T) Thrt->lchild=Thrt; //若树为空,则左指针也指向自己
|
||||
else
|
||||
{
|
||||
Thrt->lchild=T; pre=Thrt; //头结点的左孩子指向根,pre初值指向头结点
|
||||
InThreading(T); //调用算法5.7,对以T为根的二叉树进行中序线索化
|
||||
pre->rchild=Thrt; //算法5.7结束后,pre为最右结点,pre的右线索指向头结点
|
||||
pre->RTag=1;
|
||||
Thrt->rchild=pre; //头结点的右线索指向pre
|
||||
}
|
||||
} //InOrderThreading
|
||||
|
||||
void main()
|
||||
{
|
||||
pre->RTag=1;
|
||||
pre->rchild=NULL;
|
||||
BiThrTree tree,Thrt;
|
||||
cout<<"请输入建立二叉链表的序列:\n";
|
||||
CreateBiTree(tree);
|
||||
InOrderThreading(Thrt,tree);
|
||||
cout<<"线索化完毕!\n";
|
||||
}
|
||||
108
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.9.cpp
Normal file
108
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第5章/5.9.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
//算法5.9 遍历中序线索二叉树
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
//二叉树的二叉线索类型存储表示
|
||||
typedef struct BiThrNode
|
||||
{
|
||||
char data; //结点数据域
|
||||
struct BiThrNode *lchild,*rchild; //左右孩子指针
|
||||
int LTag,RTag;
|
||||
}BiThrNode,*BiThrTree;
|
||||
|
||||
//全局变量pre
|
||||
BiThrNode *pre=new BiThrNode;
|
||||
|
||||
//用算法5.3建立二叉链表
|
||||
void CreateBiTree(BiThrTree &T)
|
||||
{
|
||||
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
|
||||
char ch;
|
||||
cin >> ch;
|
||||
if(ch=='#') T=NULL; //递归结束,建空树
|
||||
else
|
||||
{
|
||||
T=new BiThrNode;
|
||||
T->data=ch; //生成根结点
|
||||
CreateBiTree(T->lchild); //递归创建左子树
|
||||
CreateBiTree(T->rchild); //递归创建右子树
|
||||
} //else
|
||||
} //CreateBiTree
|
||||
|
||||
//用算法5.7以结点P为根的子树中序线索化
|
||||
void InThreading(BiThrTree p)
|
||||
{
|
||||
//pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索
|
||||
if(p)
|
||||
{
|
||||
InThreading(p->lchild); //左子树递归线索化
|
||||
if(!p->lchild)
|
||||
{ //p的左孩子为空
|
||||
p->LTag=1; //给p加上左线索
|
||||
p->lchild=pre; //p的左孩子指针指向pre(前驱)
|
||||
}
|
||||
else
|
||||
p->LTag=0;
|
||||
if(!pre->rchild)
|
||||
{ //pre的右孩子为空
|
||||
pre->RTag=1; //给pre加上右线索
|
||||
pre->rchild=p; //pre的右孩子指针指向p(后继)
|
||||
}
|
||||
else
|
||||
pre->RTag=0;
|
||||
pre=p; //保持pre指向p的前驱
|
||||
InThreading(p->rchild); //右子树递归线索化
|
||||
}
|
||||
}//InThreading
|
||||
|
||||
//用算法5.8带头结点的中序线索化
|
||||
void InOrderThreading (BiThrTree &Thrt,BiThrTree T)
|
||||
{
|
||||
//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
|
||||
Thrt=new BiThrNode; //建头结点
|
||||
Thrt->LTag=0; //头结点有左孩子,若树非空,则其左孩子为树根
|
||||
Thrt->RTag=1; //头结点的右孩子指针为右线索
|
||||
Thrt->rchild=Thrt; //初始化时右指针指向自己
|
||||
if(!T) Thrt->lchild=Thrt; //若树为空,则左指针也指向自己
|
||||
else
|
||||
{
|
||||
Thrt->lchild=T; pre=Thrt; //头结点的左孩子指向根,pre初值指向头结点
|
||||
InThreading(T); //调用算法5.7,对以T为根的二叉树进行中序线索化
|
||||
pre->rchild=Thrt; //算法5.7结束后,pre为最右结点,pre的右线索指向头结点
|
||||
pre->RTag=1;
|
||||
Thrt->rchild=pre; //头结点的右线索指向pre
|
||||
}
|
||||
} //InOrderThreading
|
||||
|
||||
void InOrderTraverse_Thr(BiThrTree T)
|
||||
{
|
||||
//T指向头结点,头结点的左链lchild指向根结点,可参见线索化算法5.8。
|
||||
//中序遍历二叉线索树T的非递归算法,对每个数据元素直接输出
|
||||
BiThrTree p;
|
||||
p=T->lchild; //p指向根结点
|
||||
while(p!=T) //空树或遍历结束时,p==T
|
||||
{
|
||||
while(p->LTag==0) //沿左孩子向下
|
||||
p=p->lchild; //访问其左子树为空的结点
|
||||
cout<<p->data;
|
||||
while(p->RTag==1&&p->rchild!=T)
|
||||
{
|
||||
p=p->rchild; //沿右线索访问后继结点
|
||||
cout<<p->data;
|
||||
}
|
||||
p=p->rchild;
|
||||
}
|
||||
} //InOrderTraverse_Thr
|
||||
|
||||
void main()
|
||||
{
|
||||
pre->RTag=1;
|
||||
pre->rchild=NULL;
|
||||
BiThrTree tree,Thrt;
|
||||
cout<<"请输入建立二叉链表的序列:\n";
|
||||
CreateBiTree(tree);
|
||||
InOrderThreading(Thrt,tree);
|
||||
cout<<"中序遍历线索二叉树的结果为:\n";
|
||||
InOrderTraverse_Thr(Thrt);
|
||||
cout<<endl;
|
||||
}
|
||||
84
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.1.cpp
Normal file
84
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.1.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
//算法6.1 采用邻接矩阵表示法创建无向网
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define MaxInt 32767 //表示极大值,即∞
|
||||
#define MVNum 100 //最大顶点数
|
||||
#define OK 1
|
||||
|
||||
typedef char VerTexType; //假设顶点的数据类型为字符型
|
||||
typedef int ArcType; //假设边的权值类型为整型
|
||||
|
||||
//- - - - -图的邻接矩阵存储表示- - - - -
|
||||
typedef struct{
|
||||
VerTexType vexs[MVNum]; //顶点表
|
||||
ArcType arcs[MVNum][MVNum]; //邻接矩阵
|
||||
int vexnum,arcnum; //图的当前点数和边数
|
||||
}AMGraph;
|
||||
|
||||
int LocateVex(AMGraph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vexs[i] == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
int CreateUDN(AMGraph &G){
|
||||
//采用邻接矩阵表示法,创建无向网G
|
||||
int i , j , k;
|
||||
cout <<"请输入总顶点数,总边数,以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称,如a" << endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i){
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vexs[i]; //依次输入点的信息
|
||||
}
|
||||
cout << endl;
|
||||
for(i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxInt
|
||||
for(j = 0; j < G.vexnum; ++j)
|
||||
G.arcs[i][j] = MaxInt;
|
||||
cout << "输入边依附的顶点及权值,如 a b 5" << endl;
|
||||
for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵
|
||||
VerTexType v1 , v2;
|
||||
ArcType w;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点及权值:";
|
||||
cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
|
||||
G.arcs[i][j] = w; //边<v1, v2>的权值置为w
|
||||
G.arcs[j][i] = G.arcs[i][j]; //置<v1, v2>的对称边<v2, v1>的权值为w
|
||||
}//for
|
||||
return OK;
|
||||
}//CreateUDN
|
||||
|
||||
int main(){
|
||||
cout << "************算法6.1 采用邻接矩阵表示法创建无向网**************" << endl << endl;
|
||||
AMGraph G; int i , j;
|
||||
CreateUDN(G);
|
||||
|
||||
cout <<endl;
|
||||
cout << "*****邻接矩阵表示法创建的无向网*****" << endl;
|
||||
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
for(j = 0; j < G.vexnum; ++j){
|
||||
if(j != G.vexnum - 1){
|
||||
if(G.arcs[i][j] != MaxInt)
|
||||
cout << G.arcs[i][j] << "\t";
|
||||
else
|
||||
cout << "∞" << "\t";
|
||||
}
|
||||
else{
|
||||
if(G.arcs[i][j] != MaxInt)
|
||||
cout << G.arcs[i][j] <<endl;
|
||||
else
|
||||
cout << "∞" <<endl;
|
||||
}
|
||||
}
|
||||
}//for
|
||||
cout <<endl;
|
||||
return 0;
|
||||
}//main
|
||||
135
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.10.cpp
Normal file
135
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.10.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
//算法6.10 迪杰斯特拉算法
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define MaxInt 32767 //表示极大值,即∞
|
||||
#define MVNum 100 //最大顶点数
|
||||
typedef char VerTexType; //假设顶点的数据类型为字符型
|
||||
typedef int ArcType; //假设边的权值类型为整型
|
||||
|
||||
int *D=new int[MVNum]; //用于记录最短路的长度
|
||||
bool *S=new bool[MVNum]; //标记顶点是否进入S集合
|
||||
int *Path=new int[MVNum]; //用于记录最短路顶点的前驱
|
||||
|
||||
//------------图的邻接矩阵-----------------
|
||||
typedef struct{
|
||||
VerTexType vexs[MVNum]; //顶点表
|
||||
ArcType arcs[MVNum][MVNum]; //邻接矩阵
|
||||
int vexnum,arcnum; //图的当前点数和边数
|
||||
}AMGraph;
|
||||
|
||||
int LocateVex(AMGraph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vexs[i] == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
void CreateUDN(AMGraph &G){
|
||||
//采用邻接矩阵表示法,创建无向网G
|
||||
int i , j , k;
|
||||
cout <<"请输入总顶点数,总边数,以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称:,如a" << endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i){
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vexs[i]; //依次输入点的信息
|
||||
}
|
||||
cout << endl;
|
||||
for(i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxInt
|
||||
for(j = 0; j < G.vexnum; ++j)
|
||||
G.arcs[i][j] = MaxInt;
|
||||
cout << "输入边依附的顶点及权值,如a b 7" << endl;
|
||||
for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵
|
||||
VerTexType v1 , v2;
|
||||
ArcType w;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点及权值:";
|
||||
cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
|
||||
G.arcs[i][j] = w; //边<v1, v2>的权值置为w
|
||||
G.arcs[j][i] = G.arcs[i][j]; //置<v1, v2>的对称边<v2, v1>的权值为w
|
||||
}//for
|
||||
}//CreateUDN
|
||||
|
||||
void ShortestPath_DIJ(AMGraph G, int v0){
|
||||
//用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径
|
||||
int v , i , w , min;
|
||||
int n = G.vexnum; //n为G中顶点的个数
|
||||
|
||||
for(v = 0; v < n; ++v){ //n个顶点依次初始化
|
||||
S[v] = false; //S初始为空集
|
||||
D[v] = G.arcs[v0][v]; //将v0到各个终点的最短路径长度初始化为弧上的权值
|
||||
if(D[v] < MaxInt) Path [v] = v0; //如果v0和v之间有弧,则将v的前驱置为v0
|
||||
else Path [v] = -1; //如果v0和v之间无弧,则将v的前驱置为-1
|
||||
}//for
|
||||
|
||||
S[v0]=true; //将v0加入S
|
||||
D[v0]=0; //源点到源点的距离为0
|
||||
|
||||
/*―初始化结束,开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集―*/
|
||||
for(i = 1;i < n; ++i){ //对其余n-1个顶点,依次进行计算
|
||||
min= MaxInt;
|
||||
for(w = 0; w < n; ++w)
|
||||
if(!S[w] && D[w] < min){ //选择一条当前的最短路径,终点为v
|
||||
v = w;
|
||||
min = D[w];
|
||||
}//if
|
||||
S[v]=true; //将v加入S
|
||||
for(w = 0;w < n; ++w) //更新从v0出发到集合V?S上所有顶点的最短路径长度
|
||||
if(!S[w] && (D[v] + G.arcs[v][w] < D[w])){
|
||||
D[w] = D[v] + G.arcs[v][w]; //更新D[w]
|
||||
Path [w] = v; //更改w的前驱为v
|
||||
}//if
|
||||
}//for
|
||||
}//ShortestPath_DIJ
|
||||
|
||||
void DisplayPath(AMGraph G , int begin ,int temp ){
|
||||
//显示最短路
|
||||
if(Path[temp] != -1){
|
||||
DisplayPath(G , begin ,Path[temp]);
|
||||
cout << G.vexs[Path[temp]] << "-->";
|
||||
}
|
||||
}//DisplayPath
|
||||
|
||||
void main()
|
||||
{
|
||||
cout << "************算法6.10 迪杰斯特拉算法**************" << endl << endl;
|
||||
AMGraph G;
|
||||
int i , j ,num_start , num_destination;
|
||||
VerTexType start , destination;
|
||||
CreateUDN(G);
|
||||
cout <<endl;
|
||||
cout << "*****无向网G创建完成!*****" << endl;
|
||||
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
for(j = 0; j < G.vexnum; ++j){
|
||||
if(j != G.vexnum - 1){
|
||||
if(G.arcs[i][j] != MaxInt)
|
||||
cout << G.arcs[i][j] << "\t";
|
||||
else
|
||||
cout << "∞" << "\t";
|
||||
}
|
||||
else{
|
||||
if(G.arcs[i][j] != MaxInt)
|
||||
cout << G.arcs[i][j] <<endl;
|
||||
else
|
||||
cout << "∞" <<endl;
|
||||
}
|
||||
}
|
||||
}//for
|
||||
cout << endl;
|
||||
cout << "请依次输入起始点、终点名称:";
|
||||
cin >> start >> destination;
|
||||
num_start = LocateVex(G , start);
|
||||
num_destination = LocateVex(G , destination);
|
||||
ShortestPath_DIJ(G , num_start);
|
||||
cout << endl <<"最短路径为:";
|
||||
DisplayPath(G , num_start , num_destination);
|
||||
cout << G.vexs[num_destination]<<endl;
|
||||
}//main
|
||||
|
||||
111
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.11.cpp
Normal file
111
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.11.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
//算法6.11 弗洛伊德算法
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define MaxInt 32767 //表示极大值,即∞
|
||||
#define MVNum 100 //最大顶点数
|
||||
|
||||
typedef char VerTexType; //假设顶点的数据类型为字符型
|
||||
typedef int ArcType; //假设边的权值类型为整型
|
||||
|
||||
int Path[MVNum][MVNum]; //最短路径上顶点vj的前一顶点的序号
|
||||
int D[MVNum][MVNum]; //记录顶点vi和vj之间的最短路径长度
|
||||
|
||||
//------------图的邻接矩阵---------------
|
||||
typedef struct{
|
||||
VerTexType vexs[MVNum]; //顶点表
|
||||
ArcType arcs[MVNum][MVNum]; //邻接矩阵
|
||||
int vexnum,arcnum; //图的当前点数和边数
|
||||
}AMGraph;
|
||||
|
||||
int LocateVex(AMGraph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vexs[i] == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
void CreateUDN(AMGraph &G){
|
||||
//采用邻接矩阵表示法,创建有向网G
|
||||
int i , j , k;
|
||||
cout <<"请输入总顶点数,总边数,以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称,如a" << endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i){
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vexs[i]; //依次输入点的信息
|
||||
}
|
||||
cout << endl;
|
||||
for(i = 0; i < G.vexnum; ++i){ //初始化邻接矩阵,边的权值均置为极大值MaxInt
|
||||
for(j = 0; j < G.vexnum; ++j){
|
||||
if(j != i)
|
||||
G.arcs[i][j] = MaxInt;
|
||||
else
|
||||
G.arcs[i][j] = 0;
|
||||
}//for
|
||||
}//for
|
||||
|
||||
cout << "输入边依附的顶点及权值,如a b 3" << endl;
|
||||
for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵
|
||||
VerTexType v1 , v2;
|
||||
ArcType w;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点及权值:";
|
||||
cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
|
||||
G.arcs[i][j] = w; //边<v1, v2>的权值置为w
|
||||
}//for
|
||||
}//CreateUDN
|
||||
|
||||
void ShortestPath_Floyed(AMGraph G){
|
||||
//用Floyd算法求有向网G中各对顶点i和j之间的最短路径
|
||||
int i , j , k ;
|
||||
for (i = 0; i < G.vexnum; ++i) //各对结点之间初始已知路径及距离
|
||||
for(j = 0; j < G.vexnum; ++j){
|
||||
D[i][j] = G.arcs[i][j];
|
||||
if(D[i][j] < MaxInt && i != j) Path[i][j]=i; //如果i和j之间有弧,则将j的前驱置为i
|
||||
else Path [i][j] = -1; //如果i和j之间无弧,则将j的前驱置为-1
|
||||
}//for
|
||||
for(k = 0; k < G.vexnum; ++k)
|
||||
for(i = 0; i < G.vexnum; ++i)
|
||||
for(j = 0; j < G.vexnum; ++j)
|
||||
if(D[i][k] + D[k][j] < D[i][j]){ //从i经k到j的一条路径更短
|
||||
D[i][j] = D[i][k]+D[k][j]; //更新D[i][j]
|
||||
Path[i][j] = Path[k][j]; //更改j的前驱为k
|
||||
}//if
|
||||
}//ShortestPath_Floyed
|
||||
|
||||
void DisplayPath(AMGraph G , int begin ,int temp ){
|
||||
//显示最短路径
|
||||
if(Path[begin][temp] != -1){
|
||||
DisplayPath(G , begin ,Path[begin][temp]);
|
||||
cout << G.vexs[Path[begin][temp]] << "-->";
|
||||
}
|
||||
}//DisplayPath
|
||||
|
||||
void main(){
|
||||
cout << "************算法6.11 弗洛伊德算法**************" << endl << endl;
|
||||
AMGraph G;
|
||||
char start , destination;
|
||||
int num_start , num_destination;
|
||||
|
||||
CreateUDN(G);
|
||||
|
||||
cout <<endl;
|
||||
cout << "有向网G创建完成!" << endl;
|
||||
ShortestPath_Floyed(G);
|
||||
|
||||
cout << "请依次输入路径的起点与终点的名称:";
|
||||
cin >> start >> destination;
|
||||
num_start = LocateVex(G , start);
|
||||
num_destination = LocateVex(G , destination);
|
||||
|
||||
DisplayPath(G , num_start , num_destination);
|
||||
cout << G.vexs[num_destination] << endl;
|
||||
cout << "最短路径的长度为:" << D[num_start][num_destination] << endl;
|
||||
cout <<endl;
|
||||
}//main
|
||||
186
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.12.cpp
Normal file
186
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.12.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
//算法6.12 拓扑排序
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define MVNum 100 //最大顶点数
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
|
||||
typedef char VerTexType;
|
||||
|
||||
//- - - - -图的邻接表存储表示- - - - -
|
||||
typedef struct ArcNode{ //边结点
|
||||
int adjvex; //该边所指向的顶点的位置
|
||||
struct ArcNode *nextarc; //指向下一条边的指针
|
||||
}ArcNode;
|
||||
|
||||
typedef struct VNode{
|
||||
VerTexType data; //顶点信息
|
||||
ArcNode *firstarc; //指向第一条依附该顶点的边的指针
|
||||
}VNode, AdjList[MVNum]; //AdjList表示邻接表类型
|
||||
|
||||
typedef struct{
|
||||
AdjList vertices; //邻接表
|
||||
AdjList converse_vertices; //逆邻接表
|
||||
int vexnum, arcnum; //图的当前顶点数和边数
|
||||
}ALGraph;
|
||||
//- - - - - - - - - - - - - - - -
|
||||
|
||||
//- - - - -顺序栈的定义- - - - -
|
||||
typedef struct{
|
||||
int *base;
|
||||
int *top;
|
||||
int stacksize;
|
||||
}spStack;
|
||||
//- - - - - - - - - - - - - - - -
|
||||
|
||||
int indegree[MVNum]; //数组indegree存放个顶点的入度
|
||||
spStack S;
|
||||
|
||||
//------------栈的相关操作----------------------
|
||||
void InitStack(spStack &S){
|
||||
//初始化栈
|
||||
S.base = new int[MVNum];
|
||||
if(!S.base)
|
||||
exit(1);
|
||||
S.top = S.base;
|
||||
S.stacksize = MVNum;
|
||||
}//InitStack
|
||||
|
||||
void Push(spStack &S , int i){
|
||||
//进栈
|
||||
if(S.top - S.base == S.stacksize)
|
||||
return;
|
||||
*S.top++ = i;
|
||||
}//Push
|
||||
|
||||
void Pop(spStack &S , int &i){
|
||||
//出栈
|
||||
if(S.top == S.base)
|
||||
return;
|
||||
i = *--S.top;
|
||||
}//Pop
|
||||
|
||||
bool StackEmpty(spStack S){
|
||||
//判断栈是否为空
|
||||
if(S.top == S.base)
|
||||
return true;
|
||||
return false;
|
||||
}//StackEmpty
|
||||
//-------------------------------------------------
|
||||
|
||||
int LocateVex(ALGraph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vertices[i].data == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
int CreateUDG(ALGraph &G){
|
||||
//创建有向图G的邻接表、逆邻接表
|
||||
int i , k;
|
||||
|
||||
cout <<"请输入总顶点数,总边数,以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称,如a" << endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i){ //输入各点,构造表头结点表
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vertices[i].data; //输入顶点值
|
||||
G.converse_vertices[i].data = G.vertices[i].data;
|
||||
//初始化表头结点的指针域为NULL
|
||||
G.vertices[i].firstarc=NULL;
|
||||
G.converse_vertices[i].firstarc=NULL;
|
||||
}//for
|
||||
cout << endl;
|
||||
cout << "输入边依附的顶点,如a b" << endl;
|
||||
for(k = 0; k < G.arcnum;++k){ //输入各边,构造邻接表
|
||||
VerTexType v1 , v2;
|
||||
int i , j;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点:";
|
||||
cin >> v1 >> v2; //输入一条边依附的两个顶点
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2);
|
||||
//确定v1和v2在G中位置,即顶点在G.vertices中的序号
|
||||
|
||||
ArcNode *p1=new ArcNode; //生成一个新的边结点*p1
|
||||
p1->adjvex=j; //邻接点序号为j
|
||||
p1->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc=p1;
|
||||
//将新结点*p1插入顶点vi的边表头部
|
||||
|
||||
ArcNode *p2=new ArcNode; //生成一个新的边结点*p1
|
||||
p2->adjvex=i; //逆邻接点序号为i
|
||||
p2->nextarc = G.converse_vertices[j].firstarc; G.converse_vertices[j].firstarc=p2;
|
||||
//将新结点*p1插入顶点vi的边表头部
|
||||
}//for
|
||||
return OK;
|
||||
}//CreateUDG
|
||||
|
||||
void FindInDegree(ALGraph G){
|
||||
//求出各顶点的入度存入数组indegree中
|
||||
int i , count;
|
||||
|
||||
for(i = 0 ; i < G.vexnum ; i++){
|
||||
count = 0;
|
||||
ArcNode *p = G.converse_vertices[i].firstarc;
|
||||
if(p){
|
||||
while(p){
|
||||
p = p->nextarc;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
indegree[i] = count;
|
||||
}
|
||||
}//FindInDegree
|
||||
|
||||
int TopologicalSort(ALGraph G , int topo[]){
|
||||
//有向图G采用邻接表存储结构
|
||||
//若G无回路,则生成G的一个拓扑序列topo[]并返回OK,否则ERROR
|
||||
int i , m;
|
||||
FindInDegree(G); //求出各顶点的入度存入数组indegree中
|
||||
InitStack(S); //栈S初始化为空
|
||||
for(i = 0; i < G.vexnum; ++i)
|
||||
if(!indegree[i]) Push(S, i); //入度为0者进栈
|
||||
m = 0; //对输出顶点计数,初始为0
|
||||
while(!StackEmpty(S)){ //栈S非空
|
||||
Pop(S, i); //将栈顶顶点vi出栈
|
||||
topo[m]=i; //将vi保存在拓扑序列数组topo中
|
||||
++m; //对输出顶点计数
|
||||
ArcNode *p = G.vertices[i].firstarc; //p指向vi的第一个邻接点
|
||||
while(p){
|
||||
int k = p->adjvex; //vk为vi的邻接点
|
||||
--indegree[k]; //vi的每个邻接点的入度减1
|
||||
if(indegree[k] ==0) Push(S, k); //若入度减为0,则入栈
|
||||
p = p->nextarc; //p指向顶点vi下一个邻接结点
|
||||
}//while
|
||||
}//while
|
||||
|
||||
if(m < G.vexnum) return ERROR; //该有向图有回路
|
||||
else return OK;
|
||||
}//TopologicalSort
|
||||
|
||||
int main(){
|
||||
cout << "************算法6.12 拓扑排序**************" << endl << endl;
|
||||
ALGraph G;
|
||||
CreateUDG(G);
|
||||
int *topo = new int [G.vexnum];
|
||||
|
||||
cout << endl;
|
||||
cout << "有向图的邻接表、逆邻接表创建完成!" << endl << endl;
|
||||
|
||||
if(TopologicalSort(G , topo)){
|
||||
cout << "该有向图的拓扑有序序列为:";
|
||||
for(int j = 0 ; j < G.vexnum; j++){
|
||||
if(j != G.vexnum - 1)
|
||||
cout << G.vertices[topo[j]].data << " , ";
|
||||
else
|
||||
cout << G.vertices[topo[j]].data << endl << endl;
|
||||
}//for
|
||||
}
|
||||
else
|
||||
cout << "网中存在环,无法进行拓扑排序!" <<endl << endl;
|
||||
return OK;
|
||||
}//main
|
||||
242
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.13.cpp
Normal file
242
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.13.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
//算法6.13 关键路径算法
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define MVNum 100 //最大顶点数
|
||||
#define BDNum MVNum * (MVNum - 1) //最大边数
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
|
||||
typedef char VerTexType;
|
||||
|
||||
//- - - - -图的邻接表存储表示- - - - -
|
||||
typedef struct ArcNode{ //边结点
|
||||
int adjvex; //该边所指向的顶点的位置
|
||||
int weight; //权值
|
||||
struct ArcNode *nextarc; //指向下一条边的指针
|
||||
}ArcNode;
|
||||
|
||||
typedef struct VNode{
|
||||
VerTexType data; //顶点信息
|
||||
ArcNode *firstarc; //指向第一条依附该顶点的边的指针
|
||||
}VNode, AdjList[MVNum]; //AdjList表示邻接表类型
|
||||
|
||||
typedef struct{
|
||||
AdjList vertices; //邻接表
|
||||
AdjList converse_vertices; //逆邻接表
|
||||
int vexnum, arcnum; //图的当前顶点数和边数
|
||||
}ALGraph;
|
||||
//- - - - - - - - - - - - - - - -
|
||||
|
||||
//- - - - -顺序栈的定义- - - - -
|
||||
typedef struct{
|
||||
int *base;
|
||||
int *top;
|
||||
int stacksize;
|
||||
}spStack;
|
||||
//- - - - - - - - - - - - - - - -
|
||||
|
||||
int indegree[MVNum]; //数组indegree存放个顶点的入度
|
||||
int ve[BDNum]; //事件vi的最早发生时间
|
||||
int vl[BDNum]; //事件vi的最迟发生时间
|
||||
int topo[MVNum]; //记录拓扑序列的顶点序号
|
||||
spStack S;
|
||||
|
||||
//----------------栈的操作--------------------
|
||||
void InitStack(spStack &S){
|
||||
//栈的初始化
|
||||
S.base = new int[MVNum];
|
||||
if(!S.base)
|
||||
exit(1);
|
||||
S.top = S.base;
|
||||
S.stacksize = MVNum;
|
||||
}//InitStack
|
||||
|
||||
void Push(spStack &S , int i){
|
||||
//入栈
|
||||
if(S.top - S.base == S.stacksize)
|
||||
return;
|
||||
*S.top++ = i;
|
||||
}//Push
|
||||
|
||||
void Pop(spStack &S , int &i){
|
||||
//出栈
|
||||
if(S.top == S.base)
|
||||
return;
|
||||
i = *--S.top;
|
||||
}//Pop
|
||||
|
||||
bool StackEmpty(spStack S){
|
||||
//判断栈是否为空
|
||||
if(S.top == S.base)
|
||||
return true;
|
||||
return false;
|
||||
}//StackEmpty
|
||||
//---------------------------------------
|
||||
|
||||
int LocateVex(ALGraph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vertices[i].data == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
int CreateUDG(ALGraph &G){
|
||||
//创建有向图G的邻接表、逆邻接表
|
||||
int i , k;
|
||||
|
||||
cout <<"请输入总顶点数,总边数,以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称,如a" << endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i){ //输入各点,构造表头结点表
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vertices[i].data; //输入顶点值
|
||||
G.converse_vertices[i].data = G.vertices[i].data;
|
||||
//初始化表头结点的指针域为NULL
|
||||
G.vertices[i].firstarc=NULL;
|
||||
G.converse_vertices[i].firstarc=NULL;
|
||||
}//for
|
||||
cout << endl;
|
||||
|
||||
cout << "输入边依附的顶点及其权值,如a b 3" << endl;
|
||||
|
||||
for(k = 0; k < G.arcnum;++k){ //输入各边,构造邻接表
|
||||
VerTexType v1 , v2;
|
||||
int i , j , w;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点及其权值:";
|
||||
cin >> v1 >> v2 >> w; //输入一条边依附的两个顶点
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2);
|
||||
//确定v1和v2在G中位置,即顶点在G.vertices中的序号
|
||||
|
||||
ArcNode *p1=new ArcNode; //生成一个新的边结点*p1
|
||||
p1->adjvex=j; //邻接点序号为j
|
||||
p1->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc=p1;
|
||||
p1->weight = w;
|
||||
//将新结点*p1插入顶点vi的边表头部
|
||||
|
||||
ArcNode *p2=new ArcNode; //生成一个新的边结点*p1
|
||||
p2->adjvex=i; //逆邻接点序号为i
|
||||
p2->nextarc = G.converse_vertices[j].firstarc; G.converse_vertices[j].firstarc=p2;
|
||||
p2->weight = w;
|
||||
//将新结点*p1插入顶点vi的边表头部
|
||||
}//for
|
||||
return OK;
|
||||
}//CreateUDG
|
||||
|
||||
void FindInDegree(ALGraph G){
|
||||
//求出各顶点的入度存入数组indegree中
|
||||
int i , count;
|
||||
|
||||
for(i = 0 ; i < G.vexnum ; i++){
|
||||
count = 0;
|
||||
ArcNode *p = G.converse_vertices[i].firstarc;
|
||||
if(p){
|
||||
while(p){
|
||||
p = p->nextarc;
|
||||
count++;
|
||||
}
|
||||
}//if
|
||||
indegree[i] = count;
|
||||
}//for
|
||||
}//FindInDegree
|
||||
|
||||
int TopologicalOrder(ALGraph G , int topo[]){
|
||||
//有向图G采用邻接表存储结构
|
||||
//若G无回路,则生成G的一个拓扑序列topo[]并返回OK,否则ERROR
|
||||
int i , m;
|
||||
FindInDegree(G); //求出各顶点的入度存入数组indegree中
|
||||
InitStack(S); //栈S初始化为空
|
||||
for(i = 0; i < G.vexnum; ++i)
|
||||
if(!indegree[i]) Push(S, i); //入度为0者进栈
|
||||
m = 0; //对输出顶点计数,初始为0
|
||||
while(!StackEmpty(S)){ //栈S非空
|
||||
Pop(S, i); //将栈顶顶点vi出栈
|
||||
topo[m]=i; //将vi保存在拓扑序列数组topo中
|
||||
++m; //对输出顶点计数
|
||||
ArcNode *p = G.vertices[i].firstarc; //p指向vi的第一个邻接点
|
||||
while(p){
|
||||
int k = p->adjvex; //vk为vi的邻接点
|
||||
--indegree[k]; //vi的每个邻接点的入度减1
|
||||
if(indegree[k] ==0) Push(S, k); //若入度减为0,则入栈
|
||||
p = p->nextarc; //p指向顶点vi下一个邻接结点
|
||||
}//while
|
||||
}//while
|
||||
|
||||
if(m < G.vexnum) return ERROR; //该有向图有回路
|
||||
else return OK;
|
||||
}//TopologicalOrder
|
||||
|
||||
int CriticalPath(ALGraph G){
|
||||
//G为邻接表存储的有向网,输出G的各项关键活动
|
||||
int n , i , k , j , e , l;
|
||||
if (!TopologicalOrder(G, topo)) return ERROR;
|
||||
//调用拓扑排序算法,使拓扑序列保存在topo中,若调用失败,则存在有向环,返回ERROR
|
||||
n = G.vexnum; //n为顶点个数
|
||||
for(i = 0; i < n; i++) //给每个事件的最早发生时间置初值0
|
||||
ve[i] = 0;
|
||||
|
||||
|
||||
/*――――――――――按拓扑次序求每个事件的最早发生时间-――――-―――――*/
|
||||
for(i = 0;i < n; i++){
|
||||
k = topo[i]; //取得拓扑序列中的顶点序号k
|
||||
ArcNode *p = G.vertices[k].firstarc; //p指向k的第一个邻接顶点
|
||||
while(p != NULL){ //依次更新k的所有邻接顶点的最早发生时间
|
||||
j = p->adjvex; //j为邻接顶点的序号
|
||||
if(ve[j] < ve[k] + p->weight) //更新顶点j的最早发生时间ve[j]
|
||||
ve[j] = ve[k] + p->weight;
|
||||
p = p->nextarc; //p指向k的下一个邻接顶点
|
||||
} //while
|
||||
} //for
|
||||
|
||||
for(i=0;i<n;i++) //给每个事件的最迟发生时间置初值ve[n-1]
|
||||
vl[i]=ve[n-1];
|
||||
|
||||
/*――――――――――按逆拓扑次序求每个事件的最迟发生时间-――――-―――――*/
|
||||
for(i = n - 1;i >= 0; i--){
|
||||
k = topo[i]; //取得拓扑序列中的顶点序号k
|
||||
ArcNode *p = G.vertices[k].firstarc; //p指向k的第一个邻接顶点
|
||||
while(p != NULL){ //根据k的邻接点,更新k的最迟发生时间
|
||||
j = p->adjvex; //j为邻接顶点的序号
|
||||
if(vl[k] > vl[j] - p->weight) //更新顶点k的最迟发生时间vl[k]
|
||||
vl[k] = vl[j] - p->weight;
|
||||
p = p->nextarc; //p指向k的下一个邻接顶点
|
||||
}//while
|
||||
}//for
|
||||
|
||||
/*――――――――――――判断每一活动是否为关键活动-――――――-―――――*/
|
||||
cout << endl;
|
||||
cout << "关键活动路径为:";
|
||||
for(i = 0;i < n; i++){ //每次循环针对vi为活动开始点的所有活动
|
||||
ArcNode *p = G.vertices[i].firstarc; //p指向i的第一个邻接顶点
|
||||
while(p != NULL) {
|
||||
j = p->adjvex; //j为i的邻接顶点的序号
|
||||
e = ve[i]; //计算活动<vi, vj>的最早开始时间
|
||||
l = vl[j] - p->weight; //计算活动<vi, vj>的最迟开始时间
|
||||
if(e == l) //若为关键活动,则输出<vi, vj>
|
||||
cout << G.vertices[i].data << "-->" << G.vertices[j].data << " ";
|
||||
p = p->nextarc; //p指向i的下一个邻接顶点
|
||||
} //while
|
||||
} //for
|
||||
return OK;
|
||||
}//CriticalPath
|
||||
|
||||
int main(){
|
||||
cout << "************算法6.13 关键路径算法**************" << endl << endl;
|
||||
ALGraph G;
|
||||
CreateUDG(G);
|
||||
int *topo = new int [G.vexnum];
|
||||
|
||||
cout << endl;
|
||||
cout << "有向图创建完成!" << endl << endl;
|
||||
|
||||
if(!CriticalPath(G))
|
||||
cout << "网中存在环,无法进行拓扑排序!" <<endl << endl;
|
||||
cout << endl;
|
||||
return OK;
|
||||
}//main
|
||||
|
||||
143
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.14.cpp
Normal file
143
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.14.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
#include<stdio.h>
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
#include<string.h>
|
||||
#include<algorithm>
|
||||
#include<iomanip>
|
||||
#include<vector>
|
||||
#include<time.h>
|
||||
#include<queue>
|
||||
#include<stack>
|
||||
#include<iterator>
|
||||
#include<math.h>
|
||||
#include<stdlib.h>
|
||||
#include<limits.h>
|
||||
#include<map>
|
||||
//#define ONLINE_JUDGE
|
||||
#define eps 1e-8
|
||||
#define INF 0x7fffffff
|
||||
#define FOR(i,a) for((i)=0;i<(a);(i)++)
|
||||
#define MEM(a) (memset((a),0,sizeof(a)))
|
||||
#define sfs(a) scanf("%s",a)
|
||||
#define sf(a) scanf("%d",&a)
|
||||
#define sfI(a) scanf("%I64d",&a)
|
||||
#define pf(a) printf("%d\n",a)
|
||||
#define pfI(a) printf("%I64d\n",a)
|
||||
#define pfs(a) printf("%s\n",a)
|
||||
#define sfd(a,b) scanf("%d%d",&a,&b)
|
||||
#define sft(a,b,c)scanf("%d%d%d",&a,&b,&c)
|
||||
#define for1(i,a,b) for(int i=(a);i<b;i++)
|
||||
#define for2(i,a,b) for(int i=(a);i<=b;i++)
|
||||
#define for3(i,a,b)for(int i=(b);i>=a;i--)
|
||||
#define MEM1(a) memset(a,0,sizeof(a))
|
||||
#define MEM2(a) memset(a,-1,sizeof(a))
|
||||
const double PI=acos(-1.0);
|
||||
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
|
||||
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
|
||||
template<class T> inline T Min(T a,T b){return a<b?a:b;}
|
||||
template<class T> inline T Max(T a,T b){return a>b?a:b;}
|
||||
using namespace std;
|
||||
#define ll __int64
|
||||
int n,m;
|
||||
#define Mod 10
|
||||
#define N 10010
|
||||
#define M 1000010
|
||||
struct Edge{ //存储边的结构体
|
||||
int to;
|
||||
int next;
|
||||
};
|
||||
struct Node{ //存储点的结构体
|
||||
int id;
|
||||
int step;
|
||||
};
|
||||
struct sqQueue{ //队列的结构体
|
||||
Node *base;
|
||||
int front;
|
||||
int rear;
|
||||
};
|
||||
Edge edge[N]; //
|
||||
int head[N];
|
||||
int vis[N];
|
||||
int cnt;
|
||||
sqQueue Q;
|
||||
void Init(){
|
||||
memset(head,-1,sizeof head);
|
||||
cnt=0;
|
||||
}
|
||||
void addEdge(int u,int v){ //添加边
|
||||
edge[cnt].to = v;
|
||||
edge[cnt].next = head[u];
|
||||
head[u] = cnt++;
|
||||
}
|
||||
void InitQueue(sqQueue &Q){ //初始化队列
|
||||
Q.base = new Node[M];
|
||||
if(!Q.base)
|
||||
exit(OVERFLOW);
|
||||
Q.front = Q.rear = 0;
|
||||
return;
|
||||
}
|
||||
int QueueLength(sqQueue Q){ //求队列的长度
|
||||
return(Q.rear-Q.front+M)%M;
|
||||
}
|
||||
int EnQueue(sqQueue &Q,Node e){ //入队
|
||||
if((Q.rear+1)%M == Q.front)
|
||||
return 0;
|
||||
Q.base[Q.rear] = e;
|
||||
Q.rear = (Q.rear+1)%M;
|
||||
return 1;
|
||||
}
|
||||
int DeQueue(sqQueue &Q){ //出队
|
||||
if(Q.front == Q.rear)
|
||||
return 0;
|
||||
Q.front = (Q.front+1)%M;
|
||||
return 1;
|
||||
}
|
||||
Node getHead(sqQueue Q){ //得到队列头部的元素
|
||||
return Q.base[Q.front];
|
||||
}
|
||||
void bfs(){ //用bfs来搜索与初始点距离不超过7的点的个数占总数的百分比
|
||||
memset(vis,0,sizeof vis);
|
||||
InitQueue(Q);
|
||||
Node cur,next;
|
||||
cur.id = 0;
|
||||
cur.step = 0;
|
||||
EnQueue(Q,cur);
|
||||
vis[0] = 1;
|
||||
int num = 0;
|
||||
while(QueueLength(Q)){
|
||||
cur = getHead(Q);
|
||||
DeQueue(Q);
|
||||
if(cur.step>7){
|
||||
break;
|
||||
}
|
||||
num++;
|
||||
int s = cur.id;
|
||||
for(int p = head[s];p!=-1;p=edge[p].next){
|
||||
int v = edge[p].to;
|
||||
if(!vis[v]){
|
||||
next.id = v;
|
||||
next.step = cur.step + 1;
|
||||
vis[v] = 1;
|
||||
EnQueue(Q,next);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%.4f\n",num*1.0/n);
|
||||
}
|
||||
int main(){
|
||||
#ifndef ONLINE_JUDGE
|
||||
freopen("in.txt","r",stdin);
|
||||
// freopen("out.txt","w",stdout);
|
||||
#endif
|
||||
while(sfd(n,m)!=EOF){ //n为顶点的数量,m为边的数量,点的编号从0-n-1
|
||||
Init(); //初始化
|
||||
int u,v;
|
||||
for(int i=0;i<m;i++){
|
||||
scanf("%d%d",&u,&v); //输入两个相邻的点
|
||||
addEdge(u,v);
|
||||
addEdge(v,u); //无向边
|
||||
}
|
||||
bfs();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
103
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.2.cpp
Normal file
103
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.2.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
//算法6.2 采用邻接表表示法创建无向图
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define MVNum 100 //最大顶点数
|
||||
#define OK 1
|
||||
|
||||
typedef char VerTexType; //顶点信息
|
||||
typedef int OtherInfo; //和边相关的信息
|
||||
|
||||
//- - - - -图的邻接表存储表示- - - - -
|
||||
typedef struct ArcNode{ //边结点
|
||||
int adjvex; //该边所指向的顶点的位置
|
||||
struct ArcNode *nextarc; //指向下一条边的指针
|
||||
OtherInfo info; //和边相关的信息
|
||||
}ArcNode;
|
||||
|
||||
typedef struct VNode{
|
||||
VerTexType data; //顶点信息
|
||||
ArcNode *firstarc; //指向第一条依附该顶点的边的指针
|
||||
}VNode, AdjList[MVNum]; //AdjList表示邻接表类型
|
||||
|
||||
typedef struct{
|
||||
AdjList vertices; //邻接表
|
||||
int vexnum, arcnum; //图的当前顶点数和边数
|
||||
}ALGraph;
|
||||
|
||||
|
||||
int LocateVex(ALGraph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vertices[i].data == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
int CreateUDG(ALGraph &G){
|
||||
//采用邻接表表示法,创建无向图G
|
||||
int i , k;
|
||||
|
||||
cout <<"请输入总顶点数,总边数中间以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称,如 a " <<endl;
|
||||
for(i = 0; i < G.vexnum; ++i){ //输入各点,构造表头结点表
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vertices[i].data; //输入顶点值
|
||||
G.vertices[i].firstarc=NULL; //初始化表头结点的指针域为NULL
|
||||
}//for
|
||||
cout << endl;
|
||||
|
||||
cout << "请输入一条边依附的顶点,如 a b" << endl;
|
||||
for(k = 0; k < G.arcnum;++k){ //输入各边,构造邻接表
|
||||
VerTexType v1 , v2;
|
||||
int i , j;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点:";
|
||||
cin >> v1 >> v2; //输入一条边依附的两个顶点
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2);
|
||||
//确定v1和v2在G中位置,即顶点在G.vertices中的序号
|
||||
|
||||
ArcNode *p1=new ArcNode; //生成一个新的边结点*p1
|
||||
p1->adjvex=j; //邻接点序号为j
|
||||
p1->nextarc= G.vertices[i].firstarc; G.vertices[i].firstarc=p1;
|
||||
//将新结点*p1插入顶点vi的边表头部
|
||||
|
||||
ArcNode *p2=new ArcNode; //生成另一个对称的新的边结点*p2
|
||||
p2->adjvex=i; //邻接点序号为i
|
||||
p2->nextarc= G.vertices[j].firstarc; G.vertices[j].firstarc=p2;
|
||||
//将新结点*p2插入顶点vj的边表头部
|
||||
}//for
|
||||
return OK;
|
||||
}//CreateUDG
|
||||
|
||||
int main(){
|
||||
cout << "************算法6.2 采用邻接表表示法创建无向图**************" << endl << endl;
|
||||
ALGraph G;
|
||||
CreateUDG(G);
|
||||
int i;
|
||||
|
||||
cout << endl;
|
||||
cout << "*****邻接表表示法创建的无向图*****" << endl;
|
||||
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
VNode temp = G.vertices[i];
|
||||
ArcNode *p = temp.firstarc;
|
||||
if(p == NULL){
|
||||
cout << G.vertices[i].data;
|
||||
cout << endl;
|
||||
}
|
||||
else{
|
||||
cout << temp.data;
|
||||
while(p){
|
||||
cout << "->";
|
||||
cout << p->adjvex;
|
||||
p = p->nextarc;
|
||||
}
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return 0;
|
||||
}//main
|
||||
114
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.3.cpp
Normal file
114
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.3.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
//算法6.3 深度优先搜索遍历连通图的递归算法
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define MVNum 100 //最大顶点数
|
||||
typedef char VerTexType; //假设顶点的数据类型为字符型
|
||||
typedef int ArcType; //假设边的权值类型为整型
|
||||
|
||||
typedef struct{
|
||||
VerTexType vexs[MVNum]; //顶点表
|
||||
ArcType arcs[MVNum][MVNum]; //邻接矩阵
|
||||
int vexnum,arcnum; //图的当前点数和边数
|
||||
}Graph;
|
||||
|
||||
bool visited[MVNum]; //访问标志数组,其初值为"false"
|
||||
int FirstAdjVex(Graph G , int v); //返回v的第一个邻接点
|
||||
int NextAdjVex(Graph G , int v , int w); //返回v相对于w的下一个邻接点
|
||||
|
||||
int LocateVex(Graph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vexs[i] == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
void CreateUDN(Graph &G){
|
||||
//采用邻接矩阵表示法,创建无向网G
|
||||
int i , j , k;
|
||||
cout <<"请输入总顶点数,总边数 , 以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称,如 a:" << endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i){
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vexs[i]; //依次输入点的信息
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxInt
|
||||
for(j = 0; j < G.vexnum; ++j)
|
||||
G.arcs[i][j] = 0;
|
||||
cout << "输入边依附的顶点,如:a b" << endl;
|
||||
for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵
|
||||
VerTexType v1 , v2;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点:";
|
||||
cin >> v1 >> v2; //输入一条边依附的顶点及权值
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
|
||||
G.arcs[j][i] = G.arcs[i][j] = 1; //置<v1, v2>的对称边<v2, v1>的权值为w
|
||||
}//for
|
||||
}//CreateUDN
|
||||
|
||||
void DFS(Graph G, int v){ //从第v个顶点出发递归地深度优先遍历图G
|
||||
cout << G.vexs[v] << " "; visited[v] = true; //访问第v个顶点,并置访问标志数组相应分量值为true
|
||||
int w;
|
||||
for(w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w))
|
||||
//依次检查v的所有邻接点w ,FirstAdjVex(G, v)表示v的第一个邻接点
|
||||
//NextAdjVex(G, v, w)表示v相对于w的下一个邻接点,w≥0表示存在邻接点
|
||||
if(!visited[w]) DFS(G, w); //对v的尚未访问的邻接顶点w递归调用DFS
|
||||
}//DFS
|
||||
|
||||
int FirstAdjVex(Graph G , int v){
|
||||
int i;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(G.arcs[v][i] == 1 && visited[i] == false)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}//FirstAdjVex
|
||||
|
||||
int NextAdjVex(Graph G , int v , int w){
|
||||
int i;
|
||||
for(i = w ; i < G.vexnum ; ++i){
|
||||
if(G.arcs[v][i] == 1 && visited[i] == false)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}//NextAdjVex
|
||||
|
||||
int main(){
|
||||
cout << "************算法6.3 深度优先搜索遍历连通图的递归算法**************" << endl << endl;
|
||||
Graph G;
|
||||
CreateUDN(G);
|
||||
cout << endl;
|
||||
cout << "无向连通图G创建完成!" << endl << endl;
|
||||
|
||||
cout << "请输入遍历连通图的起始点:";
|
||||
VerTexType c;
|
||||
cin >> c;
|
||||
|
||||
int i;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(c == G.vexs[i])
|
||||
break;
|
||||
}
|
||||
cout << endl;
|
||||
while(i >= G.vexnum){
|
||||
cout << "该点不存在,请重新输入!" << endl;
|
||||
cout << "请输入遍历连通图的起始点:";
|
||||
cin >> c;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(c == G.vexs[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
cout << "深度优先搜索遍历连通图结果:" << endl;
|
||||
DFS(G , i);
|
||||
|
||||
cout <<endl;
|
||||
return 0;
|
||||
}//main
|
||||
105
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.4.cpp
Normal file
105
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.4.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
//算法6.4 深度优先搜索遍历非连通图
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define MVNum 100 //最大顶点数
|
||||
typedef char VerTexType; //假设顶点的数据类型为字符型
|
||||
typedef int ArcType; //假设边的权值类型为整型
|
||||
|
||||
//-------------图的邻接矩阵-----------------
|
||||
typedef struct{
|
||||
VerTexType vexs[MVNum]; //顶点表
|
||||
ArcType arcs[MVNum][MVNum]; //邻接矩阵
|
||||
int vexnum,arcnum; //图的当前点数和边数
|
||||
}Graph;
|
||||
|
||||
bool visited[MVNum]; //访问标志数组,其初值为"false"
|
||||
int FirstAdjVex(Graph G , int v); //返回v的第一个邻接点
|
||||
int NextAdjVex(Graph G , int v , int w); //返回v相对于w的下一个邻接点
|
||||
|
||||
int LocateVex(Graph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vexs[i] == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
void CreateUDN(Graph &G){
|
||||
//采用邻接矩阵表示法,创建无向网G
|
||||
int i , j , k;
|
||||
cout <<"请输入总顶点数,总边数,以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称,如a" << endl;
|
||||
for(i = 0; i < G.vexnum; ++i){
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vexs[i]; //依次输入点的信息
|
||||
}
|
||||
cout << endl;
|
||||
for(i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxInt
|
||||
for(j = 0; j < G.vexnum; ++j)
|
||||
G.arcs[i][j] = 0;
|
||||
cout << "输入边依附的顶点,如a b" << endl;
|
||||
for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵
|
||||
VerTexType v1 , v2;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点:";
|
||||
cin >> v1 >> v2; //输入一条边依附的顶点及权值
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
|
||||
G.arcs[j][i] = G.arcs[i][j] = 1; //置<v1, v2>的对称边<v2, v1>的权值为w
|
||||
}//for
|
||||
}//CreateUDN
|
||||
|
||||
void DFS(Graph G, int v){
|
||||
//从第v个顶点出发递归地深度优先遍历图G
|
||||
cout << G.vexs[v] << " "; visited[v] = true; //访问第v个顶点,并置访问标志数组相应分量值为true
|
||||
int w;
|
||||
for(w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w))
|
||||
//依次检查v的所有邻接点w ,FirstAdjVex(G, v)表示v的第一个邻接点
|
||||
//NextAdjVex(G, v, w)表示v相对于w的下一个邻接点,w≥0表示存在邻接点
|
||||
if(!visited[w]) DFS(G, w); //对v的尚未访问的邻接顶点w递归调用DFS
|
||||
}//DFS
|
||||
|
||||
void DFSTraverse(Graph G){
|
||||
//对非连通图G做深度优先遍历
|
||||
int v;
|
||||
for(v = 0; v < G.vexnum; ++v) visited[v] = false; //访问标志数组初始化
|
||||
for(v = 0; v < G.vexnum; ++v) //循环调用算法6.3
|
||||
if(!visited[v]) DFS(G, v); //对尚未访问的顶点调用DFS
|
||||
}//DFSTraverse
|
||||
|
||||
int FirstAdjVex(Graph G , int v){
|
||||
//返回v的第一个邻接点
|
||||
int i;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(G.arcs[v][i] == 1 && visited[i] == false)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}//FirstAdjVex
|
||||
|
||||
int NextAdjVex(Graph G , int v , int w){
|
||||
//返回v相对于w的下一个邻接点
|
||||
int i;
|
||||
for(i = w ; i < G.vexnum ; ++i){
|
||||
if(G.arcs[v][i] == 1 && visited[i] == false)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}//NextAdjVex
|
||||
|
||||
int main(){
|
||||
cout << "************算法6.4 深度优先搜索遍历非连通图**************" << endl << endl;
|
||||
Graph G;
|
||||
CreateUDN(G);
|
||||
cout << endl;
|
||||
cout << "无向图G创建完成!" << endl << endl;
|
||||
|
||||
cout << "深度优先搜索遍历非连通图结果:" << endl;
|
||||
DFSTraverse(G);
|
||||
|
||||
cout <<endl;
|
||||
return 0;
|
||||
}//main
|
||||
116
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.5.cpp
Normal file
116
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.5.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
//算法6.5 采用邻接矩阵表示图的深度优先搜索遍历
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define MVNum 100 //最大顶点数
|
||||
typedef char VerTexType; //假设顶点的数据类型为字符型
|
||||
typedef int ArcType; //假设边的权值类型为整型
|
||||
|
||||
//------------图的邻接矩阵------------------
|
||||
typedef struct{
|
||||
VerTexType vexs[MVNum]; //顶点表
|
||||
ArcType arcs[MVNum][MVNum]; //邻接矩阵
|
||||
int vexnum,arcnum; //图的当前点数和边数
|
||||
}Graph;
|
||||
|
||||
bool visited[MVNum]; //访问标志数组,其初值为"false"
|
||||
int FirstAdjVex(Graph G , int v); //返回v的第一个邻接点
|
||||
int NextAdjVex(Graph G , int v , int w); //返回v相对于w的下一个邻接点
|
||||
|
||||
int LocateVex(Graph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vexs[i] == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
void CreateUDN(Graph &G){
|
||||
//采用邻接矩阵表示法,创建无向网G
|
||||
int i , j , k;
|
||||
cout <<"请输入总顶点数,总边数,以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称,如a" <<endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i){
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vexs[i]; //依次输入点的信息
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxInt
|
||||
for(j = 0; j < G.vexnum; ++j)
|
||||
G.arcs[i][j] = 0;
|
||||
cout << "输入边依附的顶点,如a b" << endl;
|
||||
for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵
|
||||
VerTexType v1 , v2;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点:";
|
||||
cin >> v1 >> v2; //输入一条边依附的顶点及权值
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
|
||||
G.arcs[j][i] = G.arcs[i][j] = 1; //置<v1, v2>的对称边<v2, v1>的权值为w
|
||||
}//for
|
||||
}//CreateUDN
|
||||
|
||||
void DFS(Graph G, int v){
|
||||
//图G为邻接矩阵类型
|
||||
int w;
|
||||
cout << G.vexs[v] << " "; visited[v] = true; //访问第v个顶点,并置访问标志数组相应分量值为true
|
||||
for(w = 0; w < G.vexnum; w++) //依次检查邻接矩阵v所在的行
|
||||
if((G.arcs[v][w] != 0)&& (!visited[w])) DFS(G, w); //G.arcs[v][w]!=0表示w是v的邻接点,如果w未访问,则递归调用DFS
|
||||
}//DFS
|
||||
|
||||
int FirstAdjVex(Graph G , int v){
|
||||
//返回v的第一个邻接点
|
||||
int i;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(G.arcs[v][i] == 1 && visited[i] == false)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}//FirstAdjVex
|
||||
|
||||
int NextAdjVex(Graph G , int v , int w){
|
||||
//返回v相对于w的下一个邻接点
|
||||
int i;
|
||||
for(i = w ; i < G.vexnum ; ++i){
|
||||
if(G.arcs[v][i] == 1 && visited[i] == false)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}//NextAdjVex
|
||||
|
||||
int main(){
|
||||
cout << "************算法6.5 采用邻接矩阵表示图的深度优先搜索遍历**************" << endl << endl;
|
||||
Graph G;
|
||||
CreateUDN(G);
|
||||
cout << endl;
|
||||
cout << "无向图G创建完成!" << endl << endl;
|
||||
|
||||
cout << "请输入遍历无向图G的起始点:";
|
||||
VerTexType c;
|
||||
cin >> c;
|
||||
|
||||
int i;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(c == G.vexs[i])
|
||||
break;
|
||||
}
|
||||
cout << endl;
|
||||
while(i >= G.vexnum){
|
||||
cout << "该点不存在,请重新输入!" << endl;
|
||||
cout << "请输入遍历连通图的起始点:";
|
||||
cin >> c;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(c == G.vexs[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
cout << "深度优先搜索遍历无向图G结果:" << endl;
|
||||
DFS(G , i);
|
||||
|
||||
cout <<endl;
|
||||
return 0;
|
||||
}//main
|
||||
117
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.6.cpp
Normal file
117
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.6.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
//算法6.6 采用邻接表表示图的深度优先搜索遍历
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define MVNum 100 //最大顶点数
|
||||
typedef char VerTexType; //假设顶点的数据类型为字符型
|
||||
|
||||
//-------------图的邻接表---------------------
|
||||
typedef struct ArcNode{ //边结点
|
||||
int adjvex; //该边所指向的顶点的位置
|
||||
struct ArcNode *nextarc; //指向下一条边的指针
|
||||
}ArcNode;
|
||||
|
||||
typedef struct VNode{
|
||||
VerTexType data; //顶点信息
|
||||
ArcNode *firstarc; //指向第一条依附该顶点的边的指针
|
||||
}VNode, AdjList[MVNum]; //AdjList表示邻接表类型
|
||||
|
||||
typedef struct{
|
||||
AdjList vertices; //邻接表
|
||||
int vexnum, arcnum; //图的当前顶点数和边数
|
||||
}ALGraph;
|
||||
|
||||
bool visited[MVNum]; //访问标志数组,其初值为"false"
|
||||
|
||||
int LocateVex(ALGraph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vertices[i].data == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
void CreateUDG(ALGraph &G){
|
||||
//采用邻接表表示法,创建无向图G
|
||||
int i , k;
|
||||
|
||||
cout <<"请输入总顶点数,总边数,以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称,如a" << endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i){ //输入各点,构造表头结点表
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vertices[i].data; //输入顶点值
|
||||
G.vertices[i].firstarc=NULL; //初始化表头结点的指针域为NULL
|
||||
}//for
|
||||
cout << endl;
|
||||
|
||||
cout << "输入边依附的顶点,如a b" << endl;
|
||||
|
||||
for(k = 0; k < G.arcnum;++k){ //输入各边,构造邻接表
|
||||
VerTexType v1 , v2;
|
||||
int i , j;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点:";
|
||||
cin >> v1 >> v2; //输入一条边依附的两个顶点
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2);
|
||||
//确定v1和v2在G中位置,即顶点在G.vertices中的序号
|
||||
|
||||
ArcNode *p1=new ArcNode; //生成一个新的边结点*p1
|
||||
p1->adjvex=j; //邻接点序号为j
|
||||
p1->nextarc= G.vertices[i].firstarc; G.vertices[i].firstarc=p1;
|
||||
//将新结点*p1插入顶点vi的边表头部
|
||||
|
||||
ArcNode *p2=new ArcNode; //生成另一个对称的新的边结点*p2
|
||||
p2->adjvex=i; //邻接点序号为i
|
||||
p2->nextarc= G.vertices[j].firstarc; G.vertices[j].firstarc=p2;
|
||||
//将新结点*p2插入顶点vj的边表头部
|
||||
}//for
|
||||
}//CreateUDG
|
||||
|
||||
void DFS(ALGraph G, int v){ //图G为邻接表类型
|
||||
cout << G.vertices[v].data << " ";
|
||||
visited[v] = true; //访问第v个顶点,并置访问标志数组相应分量值为true
|
||||
ArcNode *p = G.vertices[v].firstarc; //p指向v的边链表的第一个边结点
|
||||
while(p != NULL){ //边结点非空
|
||||
int w = p->adjvex; //表示w是v的邻接点
|
||||
if(!visited[w]) DFS(G, w); //如果w未访问,则递归调用DFS
|
||||
p = p->nextarc; //p指向下一个边结点
|
||||
}
|
||||
}//DFS
|
||||
|
||||
int main(){
|
||||
cout << "************算法6.6 采用邻接表表示图的深度优先搜索遍历**************" << endl << endl;
|
||||
ALGraph G;
|
||||
CreateUDG(G);
|
||||
cout << endl;
|
||||
cout << "无向连通图G创建完成!" << endl << endl;
|
||||
|
||||
cout << "请输入遍历连通图的起始点:";
|
||||
VerTexType c;
|
||||
cin >> c;
|
||||
|
||||
int i;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(c == G.vertices[i].data)
|
||||
break;
|
||||
}
|
||||
cout << endl;
|
||||
while(i >= G.vexnum){
|
||||
cout << "该点不存在,请重新输入!" << endl;
|
||||
cout << "请输入遍历连通图的起始点:";
|
||||
cin >> c;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(c == G.vertices[i].data)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cout << "深度优先搜索遍历图结果:" << endl;
|
||||
DFS(G , i);
|
||||
|
||||
cout <<endl;
|
||||
return 0;
|
||||
}//main
|
||||
163
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.7.cpp
Normal file
163
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.7.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
//算法6.7 广度优先搜索遍历连通图
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define MVNum 100 //最大顶点数
|
||||
#define MAXQSIZE 100 //最大队列长度
|
||||
|
||||
typedef char VerTexType; //假设顶点的数据类型为字符型
|
||||
typedef int ArcType; //假设边的权值类型为整型
|
||||
bool visited[MVNum]; //访问标志数组,其初值为"false"
|
||||
|
||||
//-----图的邻接矩阵存储表示-----
|
||||
typedef struct{
|
||||
VerTexType vexs[MVNum]; //顶点表
|
||||
ArcType arcs[MVNum][MVNum]; //邻接矩阵
|
||||
int vexnum,arcnum; //图的当前点数和边数
|
||||
}Graph;
|
||||
|
||||
//----队列的定义及操作--------
|
||||
typedef struct{
|
||||
ArcType *base; //初始化的动态分配存储空间
|
||||
int front; //头指针,若队列不空,指向队头元素
|
||||
int rear; //尾指针,若队列不空,指向队尾元素的下一个位置
|
||||
}sqQueue;
|
||||
|
||||
void InitQueue(sqQueue &Q){
|
||||
//构造一个空队列Q
|
||||
Q.base = new ArcType[MAXQSIZE];
|
||||
if(!Q.base) exit(1); //存储分配失败
|
||||
Q.front = Q.rear = 0;
|
||||
}//InitQueue
|
||||
|
||||
void EnQueue(sqQueue &Q, ArcType e){
|
||||
//插入元素e为Q的新的队尾元素
|
||||
if((Q.rear + 1) % MAXQSIZE == Q.front)
|
||||
return;
|
||||
Q.base[Q.rear] = e;
|
||||
Q.rear = (Q.rear + 1) % MAXQSIZE;
|
||||
}//EnQueue
|
||||
|
||||
bool QueueEmpty(sqQueue Q){
|
||||
//判断是否为空队
|
||||
if(Q.rear == Q.front)
|
||||
return true;
|
||||
return false;
|
||||
}//QueueEmpty
|
||||
|
||||
void DeQueue(sqQueue &Q, ArcType &u){
|
||||
//队头元素出队并置为u
|
||||
u = Q.base[Q.front];
|
||||
Q.front = (Q.front + 1) % MAXQSIZE;
|
||||
}//DeQueue
|
||||
//--------------------------------------------------
|
||||
|
||||
int LocateVex(Graph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vexs[i] == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
void CreateUDN(Graph &G){
|
||||
//采用邻接矩阵表示法,创建无向网G
|
||||
int i , j , k;
|
||||
cout <<"请输入总顶点数,总边数,以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
cout << "输入点的名称,如a" << endl;
|
||||
for(i = 0; i < G.vexnum; ++i){
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vexs[i]; //依次输入点的信息
|
||||
}
|
||||
cout << endl;
|
||||
for(i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxInt
|
||||
for(j = 0; j < G.vexnum; ++j)
|
||||
G.arcs[i][j] = 0;
|
||||
cout << "输入边依附的顶点,如a b" << endl;
|
||||
for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵
|
||||
VerTexType v1 , v2;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点:";
|
||||
cin >> v1 >> v2; //输入一条边依附的顶点
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
|
||||
G.arcs[i][j] = 1; //边<v1, v2>的权值置为w
|
||||
G.arcs[j][i] = G.arcs[i][j]; //置<v1, v2>的对称边<v2, v1>的权值为w
|
||||
}//for
|
||||
}//CreateUDN
|
||||
|
||||
int FirstAdjVex(Graph G , int v){
|
||||
//返回v的第一个邻接点
|
||||
int i;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(G.arcs[v][i] == 1 && visited[i] == false)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}//FirstAdjVex
|
||||
|
||||
int NextAdjVex(Graph G , int u , int w){
|
||||
//返回v相对于w的下一个邻接点
|
||||
int i;
|
||||
for(i = w ; i < G.vexnum ; ++i){
|
||||
if(G.arcs[u][i] == 1 && visited[i] == false)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}//NextAdjVex
|
||||
|
||||
void BFS (Graph G, int v){
|
||||
//按广度优先非递归遍历连通图G
|
||||
sqQueue Q;
|
||||
ArcType u;
|
||||
ArcType w;
|
||||
|
||||
cout << G.vexs[v] << " "; visited[v] = true; //访问第v个顶点,并置访问标志数组相应分量值为true
|
||||
InitQueue(Q); //辅助队列Q初始化,置空
|
||||
EnQueue(Q, v); //v进队
|
||||
while(!QueueEmpty(Q)){ //队列非空
|
||||
DeQueue(Q, u); //队头元素出队并置为u
|
||||
for(w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w)){
|
||||
//依次检查u的所有邻接点w ,FirstAdjVex(G, u)表示u的第一个邻接点
|
||||
//NextAdjVex(G, u, w)表示u相对于w的下一个邻接点,w≥0表示存在邻接点
|
||||
if(!visited[w]){ //w为u的尚未访问的邻接顶点
|
||||
cout << G.vexs[w] << " "; visited[w] = true; //访问w,并置访问标志数组相应分量值为true
|
||||
EnQueue(Q, w); //w进队
|
||||
}//if
|
||||
}//for
|
||||
}//while
|
||||
}//BFS
|
||||
|
||||
int main(){
|
||||
cout << "************算法6.7 广度优先搜索遍历连通图**************" << endl << endl;
|
||||
Graph G;
|
||||
CreateUDN(G);
|
||||
cout << endl;
|
||||
cout << "无向连通图G创建完成!" << endl << endl;
|
||||
|
||||
cout << "请输入遍历连通图的起始点:";
|
||||
VerTexType c;
|
||||
cin >> c;
|
||||
|
||||
int i;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(c == G.vexs[i])
|
||||
break;
|
||||
}
|
||||
cout << endl;
|
||||
while(i >= G.vexnum){
|
||||
cout << "该点不存在,请重新输入!" << endl;
|
||||
cout << "请输入遍历连通图的起始点:";
|
||||
cin >> c;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(c == G.vexs[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
cout << "深度优先搜索遍历连通图结果:" << endl;
|
||||
BFS(G , i);
|
||||
|
||||
cout <<endl;
|
||||
return 0;
|
||||
}//main
|
||||
115
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.8.cpp
Normal file
115
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.8.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
//算法6.8 普里姆算法
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
typedef char VerTexType;
|
||||
typedef int ArcType;
|
||||
#define MVNum 100
|
||||
#define MaxInt 32767 //表示极大值,即∞
|
||||
|
||||
//辅助数组的定义,用来记录从顶点集U到V-U的权值最小的边
|
||||
struct{
|
||||
VerTexType adjvex; //最小边在U中的那个顶点
|
||||
ArcType lowcost; //最小边上的权值
|
||||
}closedge[MVNum];
|
||||
|
||||
//- - - - -图的邻接表存储表示- - - - -
|
||||
typedef char VerTexType; //假设顶点的数据类型为字符型
|
||||
typedef int ArcType; //假设边的权值类型为整型
|
||||
typedef struct{
|
||||
VerTexType vexs[MVNum]; //顶点表
|
||||
ArcType arcs[MVNum][MVNum]; //邻接矩阵
|
||||
int vexnum,arcnum; //图的当前点数和边数
|
||||
}AMGraph;
|
||||
|
||||
int LocateVex(AMGraph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vexs[i] == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
void CreateUDN(AMGraph &G){
|
||||
//采用邻接矩阵表示法,创建无向网G
|
||||
int i , j , k;
|
||||
cout <<"请输入总顶点数,总边数,以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称,如a" << endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i){
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vexs[i]; //依次输入点的信息
|
||||
}
|
||||
cout << endl;
|
||||
for(i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxInt
|
||||
for(j = 0; j < G.vexnum; ++j)
|
||||
G.arcs[i][j] = MaxInt;
|
||||
cout << "输入边依附的顶点及权值,如a b 5" << endl;
|
||||
for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵
|
||||
VerTexType v1 , v2;
|
||||
ArcType w;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点及权值:";
|
||||
cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
|
||||
G.arcs[i][j] = w; //边<v1, v2>的权值置为w
|
||||
G.arcs[j][i] = G.arcs[i][j]; //置<v1, v2>的对称边<v2, v1>的权值为w
|
||||
}//for
|
||||
}//CreateUDN
|
||||
|
||||
int Min(AMGraph G){
|
||||
//返回权值最小的点
|
||||
int i;
|
||||
int index = -1;
|
||||
int min = MaxInt;
|
||||
for(i = 0 ; i < G.vexnum ; ++i){
|
||||
if(min > closedge[i].lowcost && closedge[i].lowcost != 0){
|
||||
min = closedge[i].lowcost;
|
||||
index = i;
|
||||
}
|
||||
}//for
|
||||
return index;
|
||||
}//Min
|
||||
|
||||
void MiniSpanTree_Prim(AMGraph G, VerTexType u){
|
||||
//无向网G以邻接矩阵形式存储,从顶点u出发构造G的最小生成树T,输出T的各条边
|
||||
int k , j , i;
|
||||
VerTexType u0 , v0;
|
||||
k =LocateVex(G, u); //k为顶点u的下标
|
||||
for(j = 0; j < G.vexnum; ++j){ //对V-U的每一个顶点vi,初始化closedge[i]
|
||||
if(j != k){
|
||||
closedge[j].adjvex = u;
|
||||
closedge[j].lowcost = G.arcs[k][j]; //{adjvex, lowcost}
|
||||
}//if
|
||||
}//for
|
||||
closedge[k].lowcost = 0; //初始,U = {u}
|
||||
for(i = 1; i < G.vexnum; ++i){ //选择其余n-1个顶点,生成n-1条边(n= G.vexnum)
|
||||
k = Min(G);
|
||||
//求出T的下一个结点:第k个顶点,closedge[k]中存有当前最小边
|
||||
u0 = closedge[k].adjvex; //u0为最小边的一个顶点,u0∈U
|
||||
v0 = G.vexs[k]; //v0为最小边的另一个顶点,v0∈V-U
|
||||
cout << "边 " <<u0 << "--->" << v0 << endl; //输出当前的最小边(u0, v0)
|
||||
closedge[k].lowcost = 0; //第k个顶点并入U集
|
||||
for(j = 0; j < G.vexnum; ++j)
|
||||
if(G.arcs[k][j] < closedge[j].lowcost){ //新顶点并入U后重新选择最小边
|
||||
closedge[j].adjvex = G.vexs[k];
|
||||
closedge[j].lowcost = G.arcs[k][j];
|
||||
}//if
|
||||
}//for
|
||||
}//MiniSpanTree_Prim
|
||||
|
||||
int main(){
|
||||
cout << "************算法6.8 普里姆算法**************" << endl << endl;
|
||||
AMGraph G;
|
||||
CreateUDN(G);
|
||||
cout << endl;
|
||||
cout << "无向图G创建完成!" << endl;
|
||||
cout <<endl;
|
||||
|
||||
cout << "******利用普里姆算法构造最小生成树结果:******" << endl;
|
||||
MiniSpanTree_Prim(G , 'a');
|
||||
cout <<endl;
|
||||
return 0;
|
||||
}//main
|
||||
125
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.9.cpp
Normal file
125
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第6章/6.9.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
//算法6.9 克鲁斯卡尔算法
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
typedef char VerTexType; //假设顶点的数据类型为字符型
|
||||
typedef int ArcType;
|
||||
#define MVNum 100 //最大顶点数
|
||||
#define MaxInt 32767 //表示极大值,即∞
|
||||
|
||||
//----------------图的邻接矩阵---------------------
|
||||
typedef struct{
|
||||
VerTexType vexs[MVNum]; //顶点表
|
||||
ArcType arcs[MVNum][MVNum]; //邻接矩阵
|
||||
int vexnum,arcnum; //图的当前点数和边数
|
||||
}AMGraph;
|
||||
|
||||
//辅助数组Edges的定义
|
||||
struct{
|
||||
VerTexType Head; //边的始点
|
||||
VerTexType Tail; //边的终点
|
||||
ArcType lowcost; //边上的权值
|
||||
}Edge[(MVNum * (MVNum - 1)) / 2];
|
||||
|
||||
int Vexset[MVNum]; //辅助数组Vexset的定义
|
||||
|
||||
int LocateVex(AMGraph G , VerTexType v){
|
||||
//确定点v在G中的位置
|
||||
for(int i = 0; i < G.vexnum; ++i)
|
||||
if(G.vexs[i] == v)
|
||||
return i;
|
||||
return -1;
|
||||
}//LocateVex
|
||||
|
||||
void CreateUDN(AMGraph &G){
|
||||
//采用邻接矩阵表示法,创建无向网G
|
||||
int i , j , k;
|
||||
cout <<"请输入总顶点数,总边数,以空格隔开:";
|
||||
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
|
||||
cout << endl;
|
||||
|
||||
cout << "输入点的名称,如a" << endl;
|
||||
|
||||
for(i = 0; i < G.vexnum; ++i){
|
||||
cout << "请输入第" << (i+1) << "个点的名称:";
|
||||
cin >> G.vexs[i]; //依次输入点的信息
|
||||
}
|
||||
cout << endl;
|
||||
for(i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxInt
|
||||
for(j = 0; j < G.vexnum; ++j)
|
||||
G.arcs[i][j] = MaxInt;
|
||||
cout << "输入边依附的顶点及权值,如a b 6" << endl;
|
||||
for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵
|
||||
VerTexType v1 , v2;
|
||||
ArcType w;
|
||||
cout << "请输入第" << (k + 1) << "条边依附的顶点及权值:";
|
||||
cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值
|
||||
i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
|
||||
G.arcs[i][j] = w; //边<v1, v2>的权值置为w
|
||||
G.arcs[j][i] = G.arcs[i][j]; //置<v1, v2>的对称边<v2, v1>的权值为w
|
||||
Edge[k].lowcost = w;
|
||||
Edge[k].Head = v1;
|
||||
Edge[k].Tail = v2;
|
||||
}//for
|
||||
}//CreateUDN
|
||||
|
||||
//----------冒泡排序-------------------
|
||||
void Sort(AMGraph G){
|
||||
int m = G.arcnum - 2;
|
||||
int flag = 1;
|
||||
while((m > 0) && flag == 1){
|
||||
flag = 0;
|
||||
for(int j = 0 ; j <= m ; j++){
|
||||
if(Edge[j].lowcost > Edge[j+ 1].lowcost){
|
||||
flag = 1;
|
||||
|
||||
VerTexType temp_Head = Edge[j].Head;
|
||||
Edge[j].Head = Edge[j+ 1].Head;
|
||||
Edge[j + 1].Head = temp_Head;
|
||||
|
||||
|
||||
VerTexType temp_Tail = Edge[j].Tail;
|
||||
Edge[j].Tail = Edge[j+ 1].Tail;
|
||||
Edge[j + 1].Tail = temp_Tail;
|
||||
|
||||
ArcType temp_lowcost = Edge[j].lowcost;
|
||||
Edge[j].lowcost = Edge[j+ 1].lowcost;
|
||||
Edge[j + 1].lowcost = temp_lowcost;
|
||||
}//if
|
||||
}//for
|
||||
--m;
|
||||
}//while
|
||||
}//Sort
|
||||
|
||||
void MiniSpanTree_Kruskal(AMGraph G){
|
||||
//无向网G以邻接矩阵形式存储,构造G的最小生成树T,输出T的各条边
|
||||
int i , j , v1 , v2 , vs1 , vs2;
|
||||
Sort(G); //将数组Edge中的元素按权值从小到大排序
|
||||
for(i = 0; i < G.vexnum; ++i) //辅助数组,表示各顶点自成一个连通分量
|
||||
Vexset[i] = i;
|
||||
for(i = 0; i < G.arcnum; ++i){
|
||||
//依次查看排好序的数组Edge中的边是否在同一连通分量上
|
||||
v1 =LocateVex(G, Edge[i].Head); //v1为边的始点Head的下标
|
||||
v2 =LocateVex(G, Edge[i].Tail); //v2为边的终点Tail的下标
|
||||
vs1 = Vexset[v1]; //获取边Edge[i]的始点所在的连通分量vs1
|
||||
vs2 = Vexset[v2]; //获取边Edge[i]的终点所在的连通分量vs2
|
||||
if(vs1 != vs2){ //边的两个顶点分属不同的连通分量
|
||||
cout << Edge[i].Head << "-->" << Edge[i].Tail << endl; //输出此边
|
||||
for(j = 0; j < G.vexnum; ++j) //合并vs1和vs2两个分量,即两个集合统一编号
|
||||
if(Vexset[j] == vs2) Vexset[j] = vs1; //集合编号为vs2的都改为vs1
|
||||
}//if
|
||||
}//for
|
||||
}//MiniSpanTree_Kruskal
|
||||
|
||||
void main(){
|
||||
cout << "************算法6.9 克鲁斯卡尔算法**************" << endl << endl;
|
||||
AMGraph G;
|
||||
CreateUDN(G);
|
||||
|
||||
cout <<endl;
|
||||
cout << "*****无向网G创建完成!*****" << endl;
|
||||
|
||||
cout <<endl;
|
||||
MiniSpanTree_Kruskal(G);
|
||||
}///main
|
||||
67
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.1.cpp
Normal file
67
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.1.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//算法7.1 顺序查找
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 100
|
||||
#define OK 1;
|
||||
|
||||
typedef struct{
|
||||
int key;//关键字域
|
||||
}ElemType;
|
||||
|
||||
typedef struct{
|
||||
ElemType *R;
|
||||
int length;
|
||||
}SSTable;
|
||||
|
||||
int InitList_SSTable(SSTable &L)
|
||||
{
|
||||
L.R=new ElemType[MAXSIZE];
|
||||
if (!L.R)
|
||||
{
|
||||
cout<<"初始化错误";
|
||||
return 0;
|
||||
}
|
||||
L.length=0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int Insert_SSTable(SSTable &L)
|
||||
{
|
||||
int j=0;
|
||||
for(int i=0;i<MAXSIZE;i++)
|
||||
{
|
||||
L.R[i].key=j;
|
||||
L.length++;
|
||||
j++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Search_Seq(SSTable ST, int key){
|
||||
//在顺序表ST中顺序查找其关键字等于key的数据元素。若找到,则函数值为
|
||||
//该元素在表中的位置,否则为0
|
||||
for (int i=ST.length; i>=1; --i)
|
||||
if (ST.R[i].key==key) return i; //从后往前找
|
||||
return 0;
|
||||
}// Search_Seq
|
||||
|
||||
void Show_End(int result,int testkey)
|
||||
{
|
||||
if(result==0)
|
||||
cout<<"未找到"<<testkey<<endl;
|
||||
else
|
||||
cout<<"找到"<<testkey<<"位置为"<<result<<endl;
|
||||
return;
|
||||
}
|
||||
void main()
|
||||
{
|
||||
SSTable ST;
|
||||
InitList_SSTable(ST);
|
||||
Insert_SSTable(ST);
|
||||
int testkey1=7,testkey2=200;
|
||||
int result;
|
||||
result=Search_Seq(ST, testkey1);
|
||||
Show_End(result,testkey1);
|
||||
result=Search_Seq(ST, testkey2);
|
||||
Show_End(result,testkey2);
|
||||
}
|
||||
58
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.10.cpp
Normal file
58
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.10.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
//算法7.10 哈希表的查找
|
||||
//- - - - -开放地址法哈希表的存储表示- - - - -
|
||||
#define m 16 //哈希表的表长
|
||||
#define NULLKEY 0 //单元为空的标记
|
||||
|
||||
struct HashTable{
|
||||
int key; //关键字项
|
||||
// InfoType otherinfo; //其他数据项
|
||||
};
|
||||
|
||||
// 算法7.10为哈希表查找的算法,采用线性探测法处理冲突。
|
||||
// 【算法实现】
|
||||
|
||||
int H(int key)
|
||||
{
|
||||
int result;
|
||||
result=key%13;
|
||||
return result;
|
||||
}
|
||||
|
||||
int SearchHash(HashTable HT[],int key){
|
||||
//在哈希表HT中查找关键字为key的元素,若查找成功,返回哈希表的单元标号,否则返回-1
|
||||
int H0=H(key); //根据哈希函数H(key)计算哈希地址
|
||||
int Hi;
|
||||
if (HT[H0].key==NULLKEY) return -1; //若单元H0为空,则所查元素不存在
|
||||
else if (HT[H0].key==key) return H0; //若单元H0中元素的关键字为key,则查找成功
|
||||
else{
|
||||
for(int i=1;i<m;++i){
|
||||
Hi=(H0+i)%m; //按照线性探测法计算下一个哈希地址Hi
|
||||
if (HT[Hi].key==NULLKEY) return -1; //若单元Hi为空,则所查元素不存在
|
||||
else if (HT[Hi].key==key) return Hi; //若单元Hi中元素的关键字为key,则查找成功
|
||||
}//for
|
||||
return -1;
|
||||
}//else
|
||||
}//SearchHash
|
||||
|
||||
void main()
|
||||
{
|
||||
int result;
|
||||
int a[16]={-1,14,1,68,27,55,19,20,84,79,23,11,10,-1.-1.-1};
|
||||
HashTable HT[m];
|
||||
for(int i=0;i<16;i++)
|
||||
{
|
||||
HT[i].key=a[i];
|
||||
}
|
||||
result=SearchHash(HT,55);
|
||||
if(result!=-1)
|
||||
{
|
||||
cout<<"在第"<<result<<"位置找到"<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout<<"未找到"<<endl;
|
||||
}
|
||||
}
|
||||
66
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.2.cpp
Normal file
66
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.2.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
//算法7.2 设置监视哨的顺序查找
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 100
|
||||
#define OK 1;
|
||||
|
||||
typedef struct{
|
||||
int key;//关键字域
|
||||
}ElemType;
|
||||
|
||||
typedef struct{
|
||||
ElemType *R;
|
||||
int length;
|
||||
}SSTable;
|
||||
|
||||
int InitList_SSTable(SSTable &L)
|
||||
{
|
||||
L.R=new ElemType[MAXSIZE];
|
||||
if (!L.R)
|
||||
{
|
||||
cout<<"初始化错误";
|
||||
return 0;
|
||||
}
|
||||
L.length=0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int Insert_SSTable(SSTable &L)
|
||||
{
|
||||
int j=1;//空出ST.R[0]的位置
|
||||
for(int i=1;i<MAXSIZE;i++)
|
||||
{
|
||||
L.R[i].key=j;
|
||||
L.length++;
|
||||
j++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Search_Seq(SSTable ST, int key){
|
||||
//在顺序表ST中顺序查找其关键字等于key的数据元素。若找到,则函数值为
|
||||
//该元素在表中的位置,否则为0
|
||||
ST.R[0].key = key; //“哨兵”
|
||||
for(int i = ST.length; ST.R[i].key!=key; --i) ; //从后往前找
|
||||
return i;
|
||||
}// Search_Seq
|
||||
void Show_End(int result,int testkey)
|
||||
{
|
||||
if(result==0)
|
||||
cout<<"未找到"<<testkey<<endl;
|
||||
else
|
||||
cout<<"找到"<<testkey<<"位置为"<<result<<endl;
|
||||
return;
|
||||
}
|
||||
void main()
|
||||
{
|
||||
SSTable ST;
|
||||
InitList_SSTable(ST);
|
||||
Insert_SSTable(ST);
|
||||
int testkey1=7,testkey2=200;
|
||||
int result;
|
||||
result=Search_Seq(ST, testkey1);
|
||||
Show_End(result,testkey1);
|
||||
result=Search_Seq(ST, testkey2);
|
||||
Show_End(result,testkey2);
|
||||
}
|
||||
77
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.3.cpp
Normal file
77
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.3.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
//算法7.3 折半查找
|
||||
|
||||
|
||||
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 100
|
||||
#define OK 1;
|
||||
|
||||
typedef struct{
|
||||
int key;//关键字域
|
||||
}ElemType;
|
||||
|
||||
typedef struct{
|
||||
ElemType *R;
|
||||
int length;
|
||||
}SSTable;
|
||||
|
||||
int InitList_SSTable(SSTable &L)
|
||||
{
|
||||
L.R=new ElemType[MAXSIZE];
|
||||
if (!L.R)
|
||||
{
|
||||
cout<<"初始化错误";
|
||||
return 0;
|
||||
}
|
||||
L.length=0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int Insert_SSTable(SSTable &L)
|
||||
{
|
||||
int j=1;
|
||||
for(int i=1;i<MAXSIZE;i++)
|
||||
{
|
||||
L.R[i].key=j;
|
||||
L.length++;
|
||||
j++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Search_Bin(SSTable ST,int key) {
|
||||
// 在有序表ST中折半查找其关键字等于key的数据元素。若找到,则函数值为
|
||||
// 该元素在表中的位置,否则为0
|
||||
int low=1,high=ST.length; //置查找区间初值
|
||||
int mid;
|
||||
while(low<=high) {
|
||||
mid=(low+high) / 2;
|
||||
if (key==ST.R[mid].key) return mid; //找到待查元素
|
||||
else if (key<ST.R[mid].key) high = mid -1; //继续在前一子表进行查找
|
||||
else low =mid +1; //继续在后一子表进行查找
|
||||
}//while
|
||||
return 0; //表中不存在待查元素
|
||||
}// Search_Bin
|
||||
|
||||
void Show_End(int result,int testkey)
|
||||
{
|
||||
if(result==0)
|
||||
cout<<"未找到"<<testkey<<endl;
|
||||
else
|
||||
cout<<"找到"<<testkey<<"位置为"<<result<<endl;
|
||||
return;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
SSTable ST;
|
||||
InitList_SSTable(ST);
|
||||
Insert_SSTable(ST);
|
||||
int testkey1=7,testkey2=200;
|
||||
int result;
|
||||
result=Search_Bin(ST, testkey1);
|
||||
Show_End(result,testkey1);
|
||||
result=Search_Bin(ST, testkey2);
|
||||
Show_End(result,testkey2);
|
||||
}
|
||||
134
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.4-7.7.cpp
Normal file
134
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.4-7.7.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
//算法7.4 二叉排序树的递归查找
|
||||
//算法7.5 二叉排序树的插入
|
||||
//算法7.6 二叉排序树的创建
|
||||
//算法 7.7 二叉排序树的删除
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#define ENDFLAG '#'
|
||||
//char a[10]={'5','6','7','2','1','9','8','10','3','4','#'};//全局变量
|
||||
typedef struct ElemType{
|
||||
char key;
|
||||
}ElemType;
|
||||
|
||||
typedef struct BSTNode{
|
||||
ElemType data; //结点数据域
|
||||
BSTNode *lchild,*rchild; //左右孩子指针
|
||||
}BSTNode,*BSTree;
|
||||
|
||||
|
||||
//算法7.4 二叉排序树的递归查找
|
||||
BSTree SearchBST(BSTree T,char key) {
|
||||
//在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素
|
||||
//若查找成功,则返回指向该数据元素结点的指针,否则返回空指针
|
||||
if((!T)|| key==T->data.key) return T; //查找结束
|
||||
else if (key<T->data.key) return SearchBST(T->lchild,key); //在左子树中继续查找
|
||||
else return SearchBST(T->rchild,key); //在右子树中继续查找
|
||||
} // SearchBST
|
||||
|
||||
|
||||
|
||||
//算法7.5 二叉排序树的插入
|
||||
void InsertBST(BSTree &T,ElemType e ) {
|
||||
//当二叉排序树T中不存在关键字等于e.key的数据元素时,则插入该元素
|
||||
if(!T) { //找到插入位置,递归结束
|
||||
BSTree S = new BSTNode; //生成新结点*S
|
||||
S->data = e; //新结点*S的数据域置为e
|
||||
S->lchild = S->rchild = NULL; //新结点*S作为叶子结点
|
||||
T =S; //把新结点*S链接到已找到的插入位置
|
||||
}
|
||||
else if (e.key< T->data.key)
|
||||
InsertBST(T->lchild, e ); //将*S插入左子树
|
||||
else if (e.key> T->data.key)
|
||||
InsertBST(T->rchild, e); //将*S插入右子树
|
||||
}// InsertBST
|
||||
|
||||
|
||||
|
||||
//算法7.6 二叉排序树的创建
|
||||
void CreateBST(BSTree &T ) {
|
||||
//依次读入一个关键字为key的结点,将此结点插入二叉排序树T中
|
||||
T=NULL;
|
||||
ElemType e;
|
||||
cin>>e.key; //???
|
||||
while(e.key!=ENDFLAG){ //ENDFLAG为自定义常量,作为输入结束标志
|
||||
InsertBST(T, e); //将此结点插入二叉排序树T中
|
||||
cin>>e.key; //???
|
||||
}//while
|
||||
}//CreatBST
|
||||
|
||||
void DeleteBST(BSTree &T,char key) {
|
||||
//从二叉排序树T中删除关键字等于key的结点
|
||||
BSTree p=T;BSTree f=NULL; //初始化
|
||||
BSTree q;
|
||||
BSTree s;
|
||||
/*------------下面的while循环从根开始查找关键字等于key的结点*p-------------*/
|
||||
while(p){
|
||||
if (p->data.key == key) break; //找到关键字等于key的结点*p,结束循环
|
||||
f=p; //*f为*p的双亲结点
|
||||
if (p->data.key> key) p=p->lchild; //在*p的左子树中继续查找
|
||||
else p=p->rchild; //在*p的右子树中继续查找
|
||||
}//while
|
||||
if(!p) return; //找不到被删结点则返回
|
||||
/*―考虑三种情况实现p所指子树内部的处理:*p左右子树均不空、无右子树、无左子树―*/
|
||||
if ((p->lchild)&& (p->rchild)) { //被删结点*p左右子树均不空
|
||||
q = p;
|
||||
s = p->lchild;
|
||||
while (s->rchild) //在*p的左子树中继续查找其前驱结点,即最右下结点
|
||||
{q = s; s = s->rchild;} //向右到尽头
|
||||
p->data = s->data; //s指向被删结点的“前驱”
|
||||
if(q!=p){
|
||||
q->rchild = s->lchild; //重接*q的右子树
|
||||
}
|
||||
else q->lchild = s->lchild; //重接*q的左子树
|
||||
delete s;
|
||||
}//if
|
||||
else{
|
||||
if(!p->rchild) { //被删结点*p无右子树,只需重接其左子树
|
||||
q = p; p = p->lchild;
|
||||
}//else if
|
||||
else if(!p->lchild) { //被删结点*p无左子树,只需重接其右子树
|
||||
q = p; p = p->rchild;
|
||||
}//else if
|
||||
/*――――――――――将p所指的子树挂接到其双亲结点*f相应的位置――――――――*/
|
||||
if(!f) T=p; //被删结点为根结点
|
||||
else if (q==f->lchild) f->lchild = p; //挂接到*f的左子树位置
|
||||
else f->rchild = p; //挂接到*f的右子树位置
|
||||
delete q;
|
||||
}
|
||||
}//DeleteBST
|
||||
|
||||
//算法 7.7 二叉排序树的删除
|
||||
|
||||
//中序遍历
|
||||
void InOrderTraverse(BSTree &T)
|
||||
{
|
||||
if(T)
|
||||
{
|
||||
InOrderTraverse(T->lchild);
|
||||
cout<<T->data.key;
|
||||
InOrderTraverse(T->rchild);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
BSTree T;
|
||||
cout<<"请输入若干字符,用回车区分,以#结束输入"<<endl;
|
||||
CreateBST(T);
|
||||
cout<<"当前有序二叉树中序遍历结果为"<<endl;
|
||||
InOrderTraverse(T);
|
||||
char key;//待查找或待删除内容
|
||||
cout<<"请输入待查找字符"<<endl;
|
||||
cin>>key;
|
||||
BSTree result=SearchBST(T,key);
|
||||
if(result)
|
||||
{cout<<"找到字符"<<key<<endl;}
|
||||
else
|
||||
{cout<<"未找到"<<key<<endl;}
|
||||
cout<<"请输入待删除的字符"<<endl;
|
||||
cin>>key;
|
||||
DeleteBST(T,key);
|
||||
cout<<"当前有序二叉树中序遍历结果为"<<endl;
|
||||
InOrderTraverse(T);
|
||||
}
|
||||
|
||||
214
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.8-7.9.cpp
Normal file
214
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第7章/7.8-7.9.cpp
Normal file
@@ -0,0 +1,214 @@
|
||||
//算法7.8 B-树的查找
|
||||
//算法7.9 B-树的插入
|
||||
|
||||
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define OK 1
|
||||
#define m 3 //B-树的阶,暂设为3
|
||||
typedef struct BTNode{
|
||||
int keynum; //结点中关键字的个数,即结点的大小
|
||||
BTNode *parent; //指向双亲结点
|
||||
int key[m+1]; //关键字矢量,0号单元未用
|
||||
BTNode *ptr[m+1]; //子树指针矢量
|
||||
}BTNode,*BTree;
|
||||
|
||||
//- - - - - B-树的查找结果类型定义- - - - -
|
||||
struct Result{
|
||||
BTNode *pt; //指向找到的结点
|
||||
int i; //1..m,在结点中的关键字序号
|
||||
int tag; //1:查找成功,0:查找失败
|
||||
};
|
||||
|
||||
|
||||
int Search(BTree T,int key)
|
||||
{
|
||||
BTree p=T;
|
||||
int endnum;
|
||||
if(p) //树不为空时
|
||||
{
|
||||
endnum=p->keynum; //获得首节点包含的记录个数
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0; //返回没找到
|
||||
}
|
||||
int i=0;
|
||||
if(endnum==0)
|
||||
{
|
||||
return i; //树存在,但仅有一个为空根节点
|
||||
}
|
||||
else if(key>=p->key[endnum])//节点不为空,但当前值比最大的key还大
|
||||
{
|
||||
i=endnum;
|
||||
return i;
|
||||
}
|
||||
else if(key<=p->key[1]) //节点不为空,但当前值比最小的key还小
|
||||
{
|
||||
return i;}
|
||||
else
|
||||
{
|
||||
for(i=1;i<endnum;i++) //有合适的位置,即处于当前结点的最大和最小值之间,或找到了
|
||||
{
|
||||
if(p->key[i]<=key && key<p->key[i+1])
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Insert(BTree &q,int i,int x,BTree &ap)
|
||||
{//将x插入q结点的i+1位置中
|
||||
int j;
|
||||
for(j=m-1;j>i;j--)
|
||||
{
|
||||
//将插入位置之后的key全部后移一位
|
||||
q->key[j+1]=q->key[j];
|
||||
}
|
||||
for(j=m;j>i;j--)
|
||||
{
|
||||
//相应地也移动其后ptr的位置
|
||||
q->ptr[j]=q->ptr[j-1];
|
||||
}
|
||||
q->key[i+1]=x;//插入x到该位置
|
||||
q->ptr[i+1]=ap;
|
||||
q->keynum++;
|
||||
}
|
||||
|
||||
void split(BTree &q,int s,BTree &ap)
|
||||
{ //将q->key[s+1,..,m], q->ptr[s+1,..,m]移入新结点*ap作为右结点
|
||||
//原结点作为新的左侧结点
|
||||
//中间值被保存在ap[0]->key中,等待找到跳转回InsertBTree()寻找到到合适的插入位置插入
|
||||
int i;
|
||||
ap=new BTNode;
|
||||
for(i=s+1;i<=m;i++)
|
||||
{ //将q->key[s+1,..,m]保存到ap->key[0,..,m-s+1]中
|
||||
//将q->ptr[s+1,..,m]保存到ap->ptr[0,..,m-s+1]中
|
||||
ap->key[i-s-1]=q->key[i];
|
||||
ap->ptr[i-s-1]=q->ptr[i];
|
||||
}
|
||||
if(ap->ptr[0])
|
||||
{
|
||||
//当ap有子树的时候
|
||||
for(i=0;i<=1;i++)
|
||||
{
|
||||
//将ap的子树的父亲改为ap自己
|
||||
ap->ptr[i]->parent=ap;
|
||||
}
|
||||
}
|
||||
ap->keynum=(m-s)-1;
|
||||
ap->parent=q->parent;//将ap的父亲改为q的父亲
|
||||
|
||||
q->keynum=q->keynum-(m-s);//修改q的记录个数
|
||||
}
|
||||
|
||||
void NewRoot(BTree &T,BTree q,int x,BTree &ap)//生成含信息(T, x, ap)的新的根结点*T,原T和ap为子树指针
|
||||
{
|
||||
BTree newT=new BTNode;//新建一个结点作为新的根
|
||||
|
||||
newT->key[1]=x;//写入新根的key[1]
|
||||
newT->ptr[0]=T;//将原来的树根作为新根的左子树
|
||||
newT->ptr[1]=ap;//ap作为新根的右子树
|
||||
newT->keynum=1;
|
||||
newT->parent=NULL;//新根的父亲为空
|
||||
|
||||
ap->parent=newT;//ap的父亲为新根
|
||||
T->parent=newT;//T的父亲为新根
|
||||
|
||||
T=newT;//树改成新根引导的
|
||||
}
|
||||
|
||||
//算法7.9 B-树的插入
|
||||
int InsertBTree(BTree &T,int K,BTree q,int i){
|
||||
int x=K;
|
||||
BTree ap=NULL;
|
||||
int finished=FALSE;//x表示新插入的关键字,ap为一个空指针
|
||||
while(q&&!finished){
|
||||
Insert(q,i,x,ap); //将x和ap分别插入到q->key[i+1]和q->ptr[i+1]
|
||||
if (q->keynum<m)
|
||||
finished=TRUE; //插入完成
|
||||
else{ //分裂结点*q
|
||||
int s= m/2;
|
||||
split(q,s,ap);
|
||||
x=ap->key[0];// x=q->key[s];
|
||||
//将q->key[s+1..m], q->ptr[s..m]和q->recptr[s+1..m] 移入新结点*ap
|
||||
q=q->parent;
|
||||
if(q)
|
||||
{
|
||||
i=Search(q,x);
|
||||
} //在双亲结点*q中查找x的插入位置
|
||||
} //else
|
||||
} //while
|
||||
if(!finished) //T是空树(参数q初值为NULL)或者根结点已分裂为结点*q和*ap
|
||||
NewRoot(T,q,x,ap); //生成含信息(T, x, ap)的新的根结点*T,原T和ap为子树指针
|
||||
return OK;
|
||||
} //InsertBTree //InsertBTree
|
||||
|
||||
//算法7.8 B-树的查找
|
||||
Result SearchBTree(BTree &T, int key){
|
||||
/*在m阶B-树T上查找关键字key,返回结果(pt,i,tag)。若查找成功,则特征值tag=1,指针pt所指结点中第i个关键字等于key;否则特征值tag=0,等于key的关键字应插入在指针pt所指结点中第i和第i+1个关键字之间*/
|
||||
BTree p=T;
|
||||
BTree q=NULL;
|
||||
int found=FALSE;
|
||||
int i=0; //初始化,p指向待查结点,q指向p的双亲
|
||||
while(p&&!found){
|
||||
i=Search(p,key);
|
||||
//在p->key[1..keynum]中查找i,使得:p->key[i]<=key<p->key[i+1]
|
||||
if(i>0&&p->key[i]==key)
|
||||
found=TRUE; //找到待查关键字
|
||||
else
|
||||
{
|
||||
q=p;
|
||||
p=p->ptr[i];
|
||||
}
|
||||
}
|
||||
Result result;
|
||||
if(found)
|
||||
{
|
||||
result.pt=p;
|
||||
result.i=i;
|
||||
result.tag=1;
|
||||
return result;
|
||||
} //查找成功
|
||||
else
|
||||
{
|
||||
result.pt=q;
|
||||
result.i=i;
|
||||
result.tag=0;
|
||||
return result;
|
||||
} //查找不成功,返回K的插入位置信息
|
||||
}//SearchBTree
|
||||
|
||||
void InitialBTree(BTree &T)
|
||||
{
|
||||
//初始化一个空的根
|
||||
T->keynum=0;
|
||||
T->parent=NULL;
|
||||
for(int i=0;i<m+1;i++)
|
||||
{
|
||||
T->ptr[i]=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
BTree T=new BTNode;
|
||||
InitialBTree(T);
|
||||
//先用SearchBTree()找到要插入的位置,得到一个Result结构体
|
||||
//再用InsertBTree()插入数据
|
||||
Result result;
|
||||
int a[11]={45,24,53,90,3,12,50,61,70,100};
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
result=SearchBTree(T,a[i]);
|
||||
if(result.tag==0)
|
||||
{
|
||||
InsertBTree(T,a[i],result.pt,result.i);
|
||||
}
|
||||
}
|
||||
cout<<"OK";
|
||||
}
|
||||
|
||||
65
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.1.cpp
Normal file
65
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.1.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
//算法8.1 直接插入排序
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 20 //顺序表的最大长度
|
||||
typedef struct
|
||||
{
|
||||
int key;
|
||||
char *otherinfo;
|
||||
}ElemType;
|
||||
//顺序表的存储结构
|
||||
typedef struct
|
||||
{
|
||||
ElemType *r; //存储空间的基地址
|
||||
int length; //顺序表长度
|
||||
}SqList; //顺序表类型
|
||||
|
||||
void InsertSort(SqList &L)
|
||||
{
|
||||
//对顺序表L做直接插入排序
|
||||
int i,j;
|
||||
for(i=2;i<=L.length;++i)
|
||||
if(L.r[i].key<L.r[i-1].key)
|
||||
{ //"<",需将r[i]插入有序子表
|
||||
L.r[0]=L.r[i]; //将待插入的记录暂存到监视哨中
|
||||
L.r[i]=L.r[i-1]; //r[i-1]后移
|
||||
for(j=i-2; L.r[0].key<L.r[j].key;--j) //从后向前寻找插入位置
|
||||
L.r[j+1]=L.r[j]; //记录逐个后移,直到找到插入位置
|
||||
L.r[j+1]=L.r[0]; //将r[0]即原r[i],插入到正确位置
|
||||
} //if
|
||||
} //InsertSort
|
||||
|
||||
void Create_Sq(SqList &L)
|
||||
{
|
||||
int i,n;
|
||||
cout<<"请输入数据个数,不超过"<<MAXSIZE<<"个。"<<endl;
|
||||
cin>>n; //输入个数
|
||||
cout<<"请输入待排序的数据:\n";
|
||||
while(n>MAXSIZE)
|
||||
{
|
||||
cout<<"个数超过上限,不能超过"<<MAXSIZE<<",请重新输入"<<endl;
|
||||
cin>>n;
|
||||
}
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
cin>>L.r[i].key;
|
||||
L.length++;
|
||||
}
|
||||
}
|
||||
void show(SqList L)
|
||||
{
|
||||
int i;
|
||||
for(i=1;i<=L.length;i++)
|
||||
cout<<L.r[i].key<<endl;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
SqList L;
|
||||
L.r=new ElemType[MAXSIZE+1];
|
||||
L.length=0;
|
||||
Create_Sq(L);
|
||||
InsertSort(L);
|
||||
cout<<"排序后的结果为:"<<endl;
|
||||
show(L);
|
||||
}
|
||||
59
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.10.cpp
Normal file
59
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.10.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
//算法8.10 相邻两个有序子序列的归并
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 20 //顺序表的最大长度
|
||||
typedef struct
|
||||
{
|
||||
int key;
|
||||
char *otherinfo;
|
||||
}RedType;
|
||||
|
||||
void Create_Sq(RedType *R)
|
||||
{
|
||||
int i,n;
|
||||
cout<<"请输入数据个数,不超过"<<MAXSIZE<<"个。"<<endl;
|
||||
cin>>n; //输入个数
|
||||
cout<<"请输入待合并的数据:\n";
|
||||
while(n>MAXSIZE)
|
||||
{
|
||||
cout<<"个数超过上限,不能超过"<<MAXSIZE<<",请重新输入"<<endl;
|
||||
cin>>n;
|
||||
}
|
||||
for(i=0;i<n;i++)
|
||||
cin>>R[i].key;
|
||||
}
|
||||
|
||||
void Merge(RedType R[],RedType T[],int low,int mid,int high)
|
||||
{
|
||||
//将有序表R[low..mid]和R[mid+1..high]归并为有序表T[low..high]
|
||||
int i,j,k;
|
||||
i=low; j=mid+1;k=low;
|
||||
while(i<=mid&&j<=high)
|
||||
{
|
||||
//将R中记录由小到大地并入T中
|
||||
if(R[i].key<=R[j].key) T[k++]=R[i++];
|
||||
else T[k++]=R[j++];
|
||||
}
|
||||
while(i<=mid) //将剩余的R[low..mid]复制到T中
|
||||
T[k++]=R[i++];
|
||||
while(j<=high) //将剩余的R[j.high]复制到T中
|
||||
T[k++]=R[j++];
|
||||
}//Merge
|
||||
void show(RedType *T,int low,int high)
|
||||
{
|
||||
int i;
|
||||
for(i=low;i<=high;i++)
|
||||
cout<<T[i].key<<endl;
|
||||
}
|
||||
void main()
|
||||
{
|
||||
RedType *R=new RedType[MAXSIZE];
|
||||
RedType *T=new RedType[MAXSIZE];
|
||||
Create_Sq(R);
|
||||
int low,mid,high;
|
||||
cout<<"请输入第一个有序子序列的起点、终点下标和第二个有序子序列的终点下标:\n";
|
||||
cin>>low>>mid>>high;
|
||||
Merge(R,T,low,mid,high);
|
||||
cout<<"合并后的结果为:"<<endl;
|
||||
show(T,low,high);
|
||||
}
|
||||
88
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.11.cpp
Normal file
88
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.11.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
//算法8.11 归并排序
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 20 //顺序表的最大长度
|
||||
typedef struct
|
||||
{
|
||||
int key;
|
||||
char *otherinfo;
|
||||
}RedType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RedType *r;
|
||||
int length;
|
||||
}SqList;
|
||||
|
||||
void Create_Sq(SqList &L)
|
||||
{
|
||||
int i,n;
|
||||
cout<<"请输入数据个数,不超过"<<MAXSIZE<<"个。"<<endl;
|
||||
cin>>n; //输入个数
|
||||
cout<<"请输入待排序的数据:\n";
|
||||
while(n>MAXSIZE)
|
||||
{
|
||||
cout<<"个数超过上限,不能超过"<<MAXSIZE<<",请重新输入"<<endl;
|
||||
cin>>n;
|
||||
}
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
cin>>L.r[i].key;
|
||||
L.length++;
|
||||
}
|
||||
}
|
||||
|
||||
//用算法8.10 相邻两个有序子序列的归并
|
||||
void Merge(RedType R[],RedType T[],int low,int mid,int high)
|
||||
{
|
||||
//将有序表R[low..mid]和R[mid+1..high]归并为有序表T[low..high]
|
||||
int i,j,k;
|
||||
i=low; j=mid+1;k=low;
|
||||
while(i<=mid&&j<=high)
|
||||
{
|
||||
//将R中记录由小到大地并入T中
|
||||
if(R[i].key<=R[j].key) T[k++]=R[i++];
|
||||
else T[k++]=R[j++];
|
||||
}
|
||||
while(i<=mid) //将剩余的R[low..mid]复制到T中
|
||||
T[k++]=R[i++];
|
||||
while(j<=high) //将剩余的R[j.high]复制到T中
|
||||
T[k++]=R[j++];
|
||||
}//Merge
|
||||
|
||||
void MSort(RedType R[],RedType T[],int low,int high)
|
||||
{
|
||||
//R[low..high]归并排序后放入T[low..high]中
|
||||
int mid;
|
||||
RedType *S=new RedType[MAXSIZE];
|
||||
if(low==high) T[low]=R[low];
|
||||
else
|
||||
{
|
||||
mid=(low+high)/2; //将当前序列一分为二,求出分裂点mid
|
||||
MSort(R,S,low,mid); //对子序列R[low..mid] 递归归并排序,结果放入S[low..mid]
|
||||
MSort(R,S,mid+1,high); //对子序列R[mid+1..high] 递归归并排序,结果放入S[mid+1..high]
|
||||
Merge(S,T,low,mid,high); //将S[low..mid]和S [mid+1..high]归并到T[low..high]
|
||||
}//else
|
||||
}// MSort
|
||||
|
||||
void MergeSort(SqList &L)
|
||||
{
|
||||
//对顺序表L做归并排序
|
||||
MSort(L.r,L.r,1,L.length);
|
||||
}//MergeSort
|
||||
void show(SqList L)
|
||||
{
|
||||
int i;
|
||||
for(i=1;i<=L.length;i++)
|
||||
cout<<L.r[i].key<<endl;
|
||||
}
|
||||
void main()
|
||||
{
|
||||
SqList R;
|
||||
R.r=new RedType[MAXSIZE+1];
|
||||
R.length=0;
|
||||
Create_Sq(R);
|
||||
MergeSort(R);
|
||||
cout<<"排序后的结果为:"<<endl;
|
||||
show(R);
|
||||
}
|
||||
173
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.12.cpp
Normal file
173
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.12.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
//算法8.12 基数排序
|
||||
#include <iostream.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#define MAXNUM_KEY 8 //关键字项数的最大值
|
||||
#define RADIX 10 //关键字基数,此时是十进制整数的基数
|
||||
#define MAX_SPACE 10000
|
||||
typedef char KeysType; //定义关键字类型为字符型
|
||||
typedef int InfoType; //定义其它数据项的类型
|
||||
typedef struct
|
||||
{
|
||||
KeysType keys[MAXNUM_KEY]; //关键字
|
||||
InfoType otheritems; //其他数据项
|
||||
int next;
|
||||
}SLCell; //静态链表的结点类型
|
||||
typedef struct
|
||||
{
|
||||
SLCell r[MAX_SPACE]; //静态链表的可利用空间,r[0]为头结点
|
||||
int keynum; //记录的当前关键字个数
|
||||
int recnum; //静态链表的当前长度
|
||||
}SLList; //静态链表类型
|
||||
typedef int ArrType[RADIX]; //指针数组类型
|
||||
|
||||
void InitList(SLList *L)
|
||||
{
|
||||
//初始化静态链表L(把数组D中的数据存于L中)
|
||||
char c[MAXNUM_KEY],c1[MAXNUM_KEY];
|
||||
int i,j,n,max; //max为关键字的最大值
|
||||
max=-10000;
|
||||
cout<<"请输入数据个数,不超过"<<MAX_SPACE<<"个。\n";
|
||||
cin>>n;
|
||||
while(n>MAX_SPACE)
|
||||
{
|
||||
cout<<"您输入的个数超过上限,请重新输入,不超过"<<MAX_SPACE<<"个。\n";
|
||||
cin>>n;
|
||||
}
|
||||
int *D=new int[n];
|
||||
cout<<"请输入"<<n<<"个排排序的数据:\n";
|
||||
for(i=0;i<n;i++)
|
||||
{
|
||||
cin>>D[i];
|
||||
if(max<D[i])
|
||||
max=D[i];
|
||||
}
|
||||
(*L).keynum=(int)(ceil(log10(max)));
|
||||
(*L).recnum=n;
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
itoa(D[i-1],c,10); //将10进制整型转化为字符型,存入c
|
||||
for(j=strlen(c);j<(*L).keynum;j++) //若c的长度<max的位数,在c前补'0'
|
||||
{
|
||||
strcpy(c1,"0");
|
||||
strcat(c1,c);
|
||||
strcpy(c,c1);
|
||||
}
|
||||
for(j=0;j<(*L).keynum;j++)
|
||||
(*L).r[i].keys[j]=c[(*L).keynum-1-j];
|
||||
}
|
||||
}
|
||||
|
||||
int ord(char c)
|
||||
{
|
||||
//返回k的映射(个位整数)
|
||||
return c-'0';
|
||||
}
|
||||
void Distribute(SLCell *r,int i,ArrType &f,ArrType &e)
|
||||
{
|
||||
//静态链表L的r域中记录已按(keys[0], …, keys[i-1])有序
|
||||
//本算法按第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同。
|
||||
//f[0..RADIX-1]和e[0..RADIX-1]分别指向各子表中第一个和最后一个记录
|
||||
int j,p;
|
||||
for(j=0;j<RADIX;++j) f[j]=0; //各子表初始化为空表
|
||||
for(p=r[0].next;p;p=r[p].next)
|
||||
{
|
||||
j=ord(r[p].keys[i]); //ord将记录中第i个关键字映射到[0..RADIX-1]
|
||||
if(!f[j]) f[j]=p;
|
||||
else r[e[j]].next=p;
|
||||
e[j]=p; //将p所指的结点插入第j个子表中
|
||||
}//for
|
||||
}//Distribute
|
||||
|
||||
int succ(int i)
|
||||
{
|
||||
//求后继函数
|
||||
return ++i;
|
||||
}
|
||||
void Collect (SLCell *r,int i,ArrType &f,ArrType &e)
|
||||
{
|
||||
//本算法按keys[i]自小至大地将f[0..RADIX-1]所指各子表依次链接成一个链表
|
||||
//e[0..RADIX-1]为各子表的尾指针
|
||||
int j,t;
|
||||
for(j=0;!f[j];j=succ(j)); //找第一个非空子表,succ为求后继函数
|
||||
r[0].next=f[j];t=e[j]; //r[0].next指向第一个非空子表中第一个结点
|
||||
while(j<RADIX-1)
|
||||
{
|
||||
for(j=succ(j);j<RADIX-1&&!f[j];j=succ(j)) ; //找下一个非空子表
|
||||
if(f[j]) {r[t].next=f[j];t=e[j];} //链接两个非空子表
|
||||
}//while
|
||||
r[t].next=0; //t指向最后一个非空子表中的最后一个结点
|
||||
}//Collect
|
||||
|
||||
void RadixSort(SLList &L)
|
||||
{
|
||||
//L是采用静态链表表示的顺序表
|
||||
//对L做基数排序,使得L成为按关键字自小到大的有序静态链表,L.r[0]为头结点
|
||||
int i;
|
||||
ArrType f,e;
|
||||
for(i=0;i<L.recnum;++i) L.r[i].next=i+1;
|
||||
L.r[L.recnum].next = 0; //将L改造为静态链表
|
||||
for(i=0;i<L.keynum;++i)
|
||||
{
|
||||
//按最低位优先依次对各关键字进行分配和收集
|
||||
Distribute(L.r,i,f,e); //第i趟分配
|
||||
Collect(L.r,i,f,e); //第i趟收集
|
||||
}//for
|
||||
} // RadixSort
|
||||
|
||||
void print(SLList L)
|
||||
{
|
||||
//按数组序号输出静态链表
|
||||
int i,j;
|
||||
for(i=1;i<=L.recnum;i++)
|
||||
{
|
||||
for(j=L.keynum-1;j>=0;j--)
|
||||
cout<<L.r[i].keys[j];
|
||||
cout<<endl;
|
||||
}
|
||||
}
|
||||
void Sort(SLList L,int adr[])
|
||||
{
|
||||
//求得adr[1..L.length],adr[i]为静态链表L的第i个最小记录的序号
|
||||
int i=1,p=L.r[0].next;
|
||||
while(p)
|
||||
{
|
||||
adr[i++]=p;
|
||||
p=L.r[p].next;
|
||||
}
|
||||
}
|
||||
void Rearrange(SLList *L,int adr[])
|
||||
{
|
||||
//adr给出静态链表L的有序次序,即L.r[adr[i]]是第i小的记录。
|
||||
//本算法按adr重排L.r,使其有序。算法10.18(L的类型有变)
|
||||
int i,j,k;
|
||||
if(adr[i]!=i)
|
||||
{
|
||||
j=i;
|
||||
(*L).r[0]=(*L).r[i]; //暂存记录(*L).r[i]
|
||||
while(adr[j]!=i)
|
||||
{
|
||||
//调整(*L).r[adr[j]]的记录到位直到adr[j]=i为止
|
||||
k=adr[j];
|
||||
(*L).r[j]=(*L).r[k];
|
||||
adr[j]=j;
|
||||
j=k; //记录按序到位
|
||||
}
|
||||
(*L).r[j]=(*L).r[0];
|
||||
adr[j]=j;
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
SLList l;
|
||||
int *adr;
|
||||
InitList(&l);
|
||||
RadixSort(l);
|
||||
adr=new int[l.recnum];
|
||||
Sort(l,adr);
|
||||
Rearrange(&l,adr);
|
||||
cout<<"排序后(重排记录):\n";
|
||||
print(l);
|
||||
}
|
||||
69
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.2.cpp
Normal file
69
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.2.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
//算法8.2 折半插入排序
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 20 //顺序表的最大长度
|
||||
typedef struct
|
||||
{
|
||||
int key;
|
||||
char *otherinfo;
|
||||
}ElemType;
|
||||
//顺序表的存储结构
|
||||
typedef struct
|
||||
{
|
||||
ElemType *r; //存储空间的基地址
|
||||
int length; //顺序表长度
|
||||
}SqList; //顺序表
|
||||
|
||||
void BInsertSort(SqList &L){
|
||||
//对顺序表L做折半插入排序
|
||||
int i,j,low,high,m;
|
||||
for(i=2;i<=L.length;++i)
|
||||
{
|
||||
L.r[0]=L.r[i]; //将待插入的记录暂存到监视哨中
|
||||
low=1; high=i-1; //置查找区间初值
|
||||
while(low<=high)
|
||||
{ //在r[low..high]中折半查找插入的位置
|
||||
m=(low+high)/2; //折半
|
||||
if(L.r[0].key<L.r[m].key) high=m-1; //插入点在前一子表
|
||||
else low=m+1; //插入点在后一子表
|
||||
}//while
|
||||
for(j=i-1;j>=high+1;--j) L.r[j+1]=L.r[j]; //记录后移
|
||||
L.r[high+1]=L.r[0]; //将r[0]即原r[i],插入到正确位置
|
||||
} //for
|
||||
} //BInsertSort
|
||||
|
||||
void Create_Sq(SqList &L)
|
||||
{
|
||||
int i,n;
|
||||
cout<<"请输入数据个数,不超过"<<MAXSIZE<<"个。"<<endl;
|
||||
cin>>n; //输入个数
|
||||
cout<<"请输入待排序的数据:\n";
|
||||
while(n>MAXSIZE)
|
||||
{
|
||||
cout<<"个数超过上限,不能超过"<<MAXSIZE<<",请重新输入"<<endl;
|
||||
cin>>n;
|
||||
}
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
cin>>L.r[i].key;
|
||||
L.length++;
|
||||
}
|
||||
}
|
||||
|
||||
void show(SqList L)
|
||||
{
|
||||
int i;
|
||||
for(i=1;i<=L.length;i++)
|
||||
cout<<L.r[i].key<<endl;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
SqList L;
|
||||
L.r=new ElemType[MAXSIZE+1];
|
||||
L.length=0;
|
||||
Create_Sq(L);
|
||||
BInsertSort(L);
|
||||
cout<<"排序后的结果为:"<<endl;
|
||||
show(L);
|
||||
}
|
||||
82
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.3.cpp
Normal file
82
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.3.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
//算法8.3 希尔排序
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 20 //顺序表的最大长度
|
||||
typedef struct
|
||||
{
|
||||
int key;
|
||||
char *otherinfo;
|
||||
}ElemType;
|
||||
//顺序表的存储结构
|
||||
typedef struct
|
||||
{
|
||||
ElemType *r; //存储空间的基地址
|
||||
int length; //顺序表长度
|
||||
}SqList; //顺序表类型
|
||||
|
||||
void ShellInsert(SqList &L,int dk)
|
||||
{
|
||||
//对顺序表L做一趟增量是dk的希尔插入排序
|
||||
int i,j;
|
||||
for(i=dk+1;i<=L.length;++i)
|
||||
if(L.r[i].key<L.r[i-dk].key)
|
||||
{ //需将L.r[i]插入有序增量子表
|
||||
L.r[0]=L.r[i]; //暂存在L.r[0]
|
||||
for(j=i-dk;j>0&& L.r[0].key<L.r[j].key;j-=dk)
|
||||
L.r[j+dk]=L.r[j]; //记录后移,直到找到插入位置
|
||||
L.r[j+dk]=L.r[0]; //将r[0]即原r[i],插入到正确位置
|
||||
} //for
|
||||
}
|
||||
//ShellInsert
|
||||
void ShellSort(SqList &L,int dt[ ],int t){
|
||||
//按增量序列dt[0..t-1]对顺序表L作t趟希尔排序
|
||||
int k;
|
||||
for(k=0;k<t;++k)
|
||||
ShellInsert(L,dt[k]); //一趟增量为dt[t]的希尔插入排序
|
||||
} //ShellSort
|
||||
|
||||
void Create_Sq(SqList &L)
|
||||
{
|
||||
int i,n;
|
||||
cout<<"请输入数据个数,不超过"<<MAXSIZE<<"个。"<<endl;
|
||||
cin>>n; //输入个数
|
||||
cout<<"请输入待排序的数据:\n";
|
||||
while(n>MAXSIZE)
|
||||
{
|
||||
cout<<"个数超过上限,不能超过"<<MAXSIZE<<",请重新输入"<<endl;
|
||||
cin>>n;
|
||||
}
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
cin>>L.r[i].key;
|
||||
L.length++;
|
||||
}
|
||||
}
|
||||
|
||||
void show(SqList L)
|
||||
{
|
||||
int i;
|
||||
for(i=1;i<=L.length;i++)
|
||||
cout<<L.r[i].key<<endl;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
SqList L;
|
||||
L.r=new ElemType[MAXSIZE+1];
|
||||
L.length=0;
|
||||
Create_Sq(L);
|
||||
|
||||
int i,t;//增量数组的长度
|
||||
int *dt=new int[MAXSIZE];//增量数组
|
||||
cout<<"请输入增量个数:\n";
|
||||
cin>>t;
|
||||
for(i=0;i<t;i++)
|
||||
{
|
||||
cout<<"第"<<i+1<<"个增量:\n";
|
||||
cin>>dt[i];
|
||||
}
|
||||
ShellSort(L,dt,t);
|
||||
cout<<"排序后的结果为:"<<endl;
|
||||
show(L);
|
||||
}
|
||||
70
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.4.cpp
Normal file
70
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.4.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
//算法8.4 冒泡排序
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 20 //顺序表的最大长度
|
||||
typedef struct
|
||||
{
|
||||
int key;
|
||||
char *otherinfo;
|
||||
}ElemType;
|
||||
//顺序表的存储结构
|
||||
typedef struct
|
||||
{
|
||||
ElemType *r; //存储空间的基地址
|
||||
int length; //顺序表长度
|
||||
}SqList; //顺序表类型
|
||||
|
||||
void BubbleSort(SqList &L)
|
||||
{
|
||||
//对顺序表L做冒泡排序
|
||||
int m,j,flag;
|
||||
ElemType t;
|
||||
m=L.length-1; flag=1; //flag用来标记某一趟排序是否发生交换
|
||||
while((m>0)&&(flag==1))
|
||||
{
|
||||
flag=0; //flag置为0,如果本趟排序没有发生交换,则不会执行下一趟排序
|
||||
for(j=1;j<=m;j++)
|
||||
if(L.r[j].key>L.r[j+1].key)
|
||||
{
|
||||
flag=1; //flag置为1,表示本趟排序发生了交换
|
||||
t=L.r[j];L.r[j]=L.r[j+1];L.r[j+1]=t; //交换前后两个记录
|
||||
} //if
|
||||
--m;
|
||||
} //while
|
||||
} //BubbleSort
|
||||
|
||||
void Create_Sq(SqList &L)
|
||||
{
|
||||
int i,n;
|
||||
cout<<"请输入数据个数,不超过"<<MAXSIZE<<"个。"<<endl;
|
||||
cin>>n; //输入个数
|
||||
cout<<"请输入待排序的数据:\n";
|
||||
while(n>MAXSIZE)
|
||||
{
|
||||
cout<<"个数超过上限,不能超过"<<MAXSIZE<<",请重新输入"<<endl;
|
||||
cin>>n;
|
||||
}
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
cin>>L.r[i].key;
|
||||
L.length++;
|
||||
}
|
||||
}
|
||||
|
||||
void show(SqList L)
|
||||
{
|
||||
int i;
|
||||
for(i=1;i<=L.length;i++)
|
||||
cout<<L.r[i].key<<endl;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
SqList L;
|
||||
L.r=new ElemType[MAXSIZE+1];
|
||||
L.length=0;
|
||||
Create_Sq(L);
|
||||
BubbleSort(L);
|
||||
cout<<"排序后的结果为:"<<endl;
|
||||
show(L);
|
||||
}
|
||||
89
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.5.cpp
Normal file
89
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.5.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
//算法8.5 快速排序
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 20 //顺序表的最大长度
|
||||
typedef struct
|
||||
{
|
||||
int key;
|
||||
char *otherinfo;
|
||||
}ElemType;
|
||||
//顺序表的存储结构
|
||||
typedef struct
|
||||
{
|
||||
ElemType *r; //存储空间的基地址
|
||||
int length; //顺序表长度
|
||||
}SqList; //顺序表类型
|
||||
|
||||
|
||||
int Partition(SqList &L,int low,int high)
|
||||
{
|
||||
//对顺序表L中的子表r[low..high]进行一趟排序,返回枢轴位置
|
||||
int pivotkey;
|
||||
L.r[0]=L.r[low]; //用子表的第一个记录做枢轴记录
|
||||
pivotkey=L.r[low].key; //枢轴记录关键字保存在pivotkey中
|
||||
while(low<high)
|
||||
{ //从表的两端交替地向中间扫描
|
||||
while(low<high&&L.r[high].key>=pivotkey) --high;
|
||||
L.r[low]=L.r[high]; //将比枢轴记录小的记录移到低端
|
||||
while(low<high&&L.r[low].key<=pivotkey) ++low;
|
||||
L.r[high]=L.r[low]; //将比枢轴记录大的记录移到高端
|
||||
}//while
|
||||
L.r[low]=L.r[0]; //枢轴记录到位
|
||||
return low; //返回枢轴位置
|
||||
}//Partition
|
||||
|
||||
void QSort(SqList &L,int low,int high)
|
||||
{ //调用前置初值:low=1; high=L.length;
|
||||
//对顺序表L中的子序列L.r[low..high]做快速排序
|
||||
int pivotloc;
|
||||
if(low<high)
|
||||
{ //长度大于1
|
||||
pivotloc=Partition(L,low,high); //将L.r[low..high]一分为二,pivotloc是枢轴位置
|
||||
QSort(L,low,pivotloc-1); //对左子表递归排序
|
||||
QSort(L,pivotloc+1,high); //对右子表递归排序
|
||||
}
|
||||
} //QSort
|
||||
|
||||
void QuickSort(SqList &L)
|
||||
{
|
||||
//对顺序表L做快速排序
|
||||
QSort(L,1,L.length);
|
||||
} //QuickSort
|
||||
|
||||
void Create_Sq(SqList &L)
|
||||
{
|
||||
int i,n;
|
||||
cout<<"请输入数据个数,不超过"<<MAXSIZE<<"个。"<<endl;
|
||||
cin>>n; //输入个数
|
||||
cout<<"请输入待排序的数据:\n";
|
||||
while(n>MAXSIZE)
|
||||
{
|
||||
cout<<"个数超过上限,不能超过"<<MAXSIZE<<",请重新输入"<<endl;
|
||||
cin>>n;
|
||||
}
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
cin>>L.r[i].key;
|
||||
L.length++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void show(SqList L)
|
||||
{
|
||||
int i;
|
||||
for(i=1;i<=L.length;i++)
|
||||
cout<<L.r[i].key<<endl;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
SqList L;
|
||||
L.r=new ElemType[MAXSIZE+1];
|
||||
L.length=0;
|
||||
Create_Sq(L);
|
||||
QuickSort(L);
|
||||
cout<<"排序后的结果为:"<<endl;
|
||||
show(L);
|
||||
}
|
||||
65
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.6.cpp
Normal file
65
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.6.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
//算法8.6 简单选择排序
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 20 //顺序表的最大长度
|
||||
typedef struct
|
||||
{
|
||||
int key;
|
||||
char *otherinfo;
|
||||
}ElemType;
|
||||
//顺序表的存储结构
|
||||
typedef struct
|
||||
{
|
||||
ElemType *r; //存储空间的基地址
|
||||
int length; //顺序表长度
|
||||
}SqList; //顺序表类型
|
||||
|
||||
void SelectSort(SqList &L)
|
||||
{
|
||||
//对顺序表L做简单选择排序
|
||||
int i,j,k;
|
||||
ElemType t;
|
||||
for(i=1;i<L.length;++i)
|
||||
{ //在L.r[i..L.length] 中选择关键字最小的记录
|
||||
k=i;
|
||||
for(j=i+1;j<=L.length;++j)
|
||||
if(L.r[j].key<L.r[k].key) k=j; //k指向此趟排序中关键字最小的记录
|
||||
if(k!=i) {t=L.r[i];L.r[i]=L.r[k];L.r[k]=t;} //交换r[i]与r[k]
|
||||
} //for
|
||||
} // SelectSort
|
||||
|
||||
void Create_Sq(SqList &L)
|
||||
{
|
||||
int i,n;
|
||||
cout<<"请输入数据个数,不超过"<<MAXSIZE<<"个。"<<endl;
|
||||
cin>>n; //输入个数
|
||||
cout<<"请输入待排序的数据:\n";
|
||||
while(n>MAXSIZE)
|
||||
{
|
||||
cout<<"个数超过上限,不能超过"<<MAXSIZE<<",请重新输入"<<endl;
|
||||
cin>>n;
|
||||
}
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
cin>>L.r[i].key;
|
||||
L.length++;
|
||||
}
|
||||
}
|
||||
|
||||
void show(SqList L)
|
||||
{
|
||||
int i;
|
||||
for(i=1;i<=L.length;i++)
|
||||
cout<<L.r[i].key<<endl;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
SqList L;
|
||||
L.r=new ElemType[MAXSIZE+1];
|
||||
L.length=0;
|
||||
Create_Sq(L);
|
||||
SelectSort(L);
|
||||
cout<<"排序后的结果为:"<<endl;
|
||||
show(L);
|
||||
}
|
||||
64
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.7.cpp
Normal file
64
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.7.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
//算法8.7 筛选法调整堆
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 20 //顺序表的最大长度
|
||||
typedef struct
|
||||
{
|
||||
int key;
|
||||
char *otherinfo;
|
||||
}ElemType;
|
||||
//顺序表的存储结构
|
||||
typedef struct
|
||||
{
|
||||
ElemType *r; //存储空间的基地址
|
||||
int length; //顺序表长度
|
||||
}SqList; //顺序表类型
|
||||
|
||||
void HeapAdjust(SqList &L,int s,int m)
|
||||
{
|
||||
//假设r[s+1..m]已经是堆,将r[s..m]调整为以r[s]为根的大根堆
|
||||
ElemType rc;
|
||||
int j;
|
||||
rc=L.r[s];
|
||||
for(j=2*s;j<=m;j*=2)
|
||||
{ //沿key较大的孩子结点向下筛选
|
||||
if(j<m&&L.r[j].key<L.r[j+1].key) ++j; //j为key较大的记录的下标
|
||||
if(rc.key>=L.r[j].key) break; //rc应插入在位置s上
|
||||
L.r[s]=L.r[j]; s=j;
|
||||
}
|
||||
L.r[s]=rc; //插入
|
||||
} //HeapAdjust
|
||||
|
||||
void Create_Sq(SqList &L)
|
||||
{
|
||||
int i,n;
|
||||
cout<<"请输入数据个数,不超过"<<MAXSIZE<<"个。"<<endl;
|
||||
cin>>n; //输入个数
|
||||
cout<<"请输入待调整的数据:\n";
|
||||
while(n>MAXSIZE)
|
||||
{
|
||||
cout<<"个数超过上限,不能超过"<<MAXSIZE<<",请重新输入"<<endl;
|
||||
cin>>n;
|
||||
}
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
cin>>L.r[i].key;
|
||||
L.length++;
|
||||
}
|
||||
}
|
||||
void show(SqList L)
|
||||
{
|
||||
int i;
|
||||
for(i=1;i<=L.length;i++)
|
||||
cout<<L.r[i].key<<endl;
|
||||
}
|
||||
void main()
|
||||
{
|
||||
SqList L;
|
||||
L.r=new ElemType[MAXSIZE+1];
|
||||
L.length=0;
|
||||
Create_Sq(L);
|
||||
HeapAdjust(L,1,L.length);
|
||||
cout<<"调整后的结果为:"<<endl;
|
||||
show(L);
|
||||
}
|
||||
75
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.8.cpp
Normal file
75
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.8.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
//算法8.8 建初堆
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 20 //顺序表的最大长度
|
||||
typedef struct
|
||||
{
|
||||
int key;
|
||||
char *otherinfo;
|
||||
}ElemType;
|
||||
//顺序表的存储结构
|
||||
typedef struct
|
||||
{
|
||||
ElemType *r; //存储空间的基地址
|
||||
int length; //顺序表长度
|
||||
}SqList; //顺序表类型
|
||||
|
||||
//用算法8.7 筛选法调整堆
|
||||
void HeapAdjust(SqList &L,int s,int m)
|
||||
{
|
||||
//假设r[s+1..m]已经是堆,将r[s..m]调整为以r[s]为根的大根堆
|
||||
ElemType rc;
|
||||
int j;
|
||||
rc=L.r[s];
|
||||
for(j=2*s;j<=m;j*=2)
|
||||
{ //沿key较大的孩子结点向下筛选
|
||||
if(j<m&&L.r[j].key<L.r[j+1].key) ++j; //j为key较大的记录的下标
|
||||
if(rc.key>=L.r[j].key) break; //rc应插入在位置s上
|
||||
L.r[s]=L.r[j]; s=j;
|
||||
}
|
||||
L.r[s]=rc; //插入
|
||||
} //HeapAdjust
|
||||
|
||||
void Create_Sq(SqList &L)
|
||||
{
|
||||
int i,n;
|
||||
cout<<"请输入数据个数,不超过"<<MAXSIZE<<"个。"<<endl;
|
||||
cin>>n; //输入个数
|
||||
cout<<"请输入数据:\n";
|
||||
while(n>MAXSIZE)
|
||||
{
|
||||
cout<<"个数超过上限,不能超过"<<MAXSIZE<<",请重新输入"<<endl;
|
||||
cin>>n;
|
||||
}
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
cin>>L.r[i].key;
|
||||
L.length++;
|
||||
}
|
||||
}
|
||||
|
||||
void CreatHeap(SqList &L)
|
||||
{
|
||||
//把无序序列L.r[1..n]建成大根堆
|
||||
int i,n;
|
||||
n=L.length;
|
||||
for(i=n/2;i>0;--i) //反复调用HeapAdjust
|
||||
HeapAdjust(L,i,n);
|
||||
} //CreatHeap
|
||||
void show(SqList L)
|
||||
{
|
||||
int i;
|
||||
for(i=1;i<=L.length;i++)
|
||||
cout<<L.r[i].key<<endl;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
SqList L;
|
||||
L.r=new ElemType[MAXSIZE+1];
|
||||
L.length=0;
|
||||
Create_Sq(L);
|
||||
CreatHeap(L);
|
||||
cout<<"建立成堆的序列为:"<<endl;
|
||||
show(L);
|
||||
}
|
||||
90
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.9.cpp
Normal file
90
数据结构/严版教材/数据结构第2版-书中算法(C语言版)/第8章/8.9.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
//算法8.9 堆排序
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define MAXSIZE 20 //顺序表的最大长度
|
||||
typedef struct
|
||||
{
|
||||
int key;
|
||||
char *otherinfo;
|
||||
}ElemType;
|
||||
//顺序表的存储结构
|
||||
typedef struct
|
||||
{
|
||||
ElemType *r; //存储空间的基地址
|
||||
int length; //顺序表长度
|
||||
}SqList; //顺序表类型
|
||||
|
||||
//用算法8.7 筛选法调整堆
|
||||
void HeapAdjust(SqList &L,int s,int m)
|
||||
{
|
||||
//假设r[s+1..m]已经是堆,将r[s..m]调整为以r[s]为根的大根堆
|
||||
ElemType rc;
|
||||
int j;
|
||||
rc=L.r[s];
|
||||
for(j=2*s;j<=m;j*=2)
|
||||
{ //沿key较大的孩子结点向下筛选
|
||||
if(j<m&&L.r[j].key<L.r[j+1].key) ++j; //j为key较大的记录的下标
|
||||
if(rc.key>=L.r[j].key) break; //rc应插入在位置s上
|
||||
L.r[s]=L.r[j]; s=j;
|
||||
}
|
||||
L.r[s]=rc; //插入
|
||||
}
|
||||
//HeapAdjust
|
||||
void Create_Sq(SqList &L)
|
||||
{
|
||||
int i,n;
|
||||
cout<<"请输入数据个数,不超过"<<MAXSIZE<<"个。"<<endl;
|
||||
cin>>n; //输入个数
|
||||
cout<<"请输入待排序的数据:\n";
|
||||
while(n>MAXSIZE)
|
||||
{
|
||||
cout<<"个数超过上限,不能超过"<<MAXSIZE<<",请重新输入"<<endl;
|
||||
cin>>n;
|
||||
}
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
cin>>L.r[i].key;
|
||||
L.length++;
|
||||
}
|
||||
}
|
||||
|
||||
//用算法8.8 建初堆
|
||||
void CreatHeap(SqList &L)
|
||||
{
|
||||
//把无序序列L.r[1..n]建成大根堆
|
||||
int i,n;
|
||||
n=L.length;
|
||||
for(i=n/2;i>0;--i) //反复调用HeapAdjust
|
||||
HeapAdjust(L,i,n);
|
||||
} //CreatHeap
|
||||
|
||||
void HeapSort(SqList &L)
|
||||
{
|
||||
//对顺序表L进行堆排序
|
||||
int i;
|
||||
ElemType x;
|
||||
CreatHeap(L); //把无序序列L.r[1..L.length]建成大根堆
|
||||
for(i=L.length;i>1;--i)
|
||||
{
|
||||
x=L.r[1]; //将堆顶记录和当前未经排序子序列L.r[1..i]中最后一个记录互换
|
||||
L.r[1]=L.r[i];
|
||||
L.r[i]=x;
|
||||
HeapAdjust(L,1,i-1); //将L.r[1..i-1]重新调整为大根堆
|
||||
}//for
|
||||
}//HeapSort
|
||||
void show(SqList L)
|
||||
{
|
||||
int i;
|
||||
for(i=1;i<=L.length;i++)
|
||||
cout<<L.r[i].key<<endl;
|
||||
}
|
||||
void main()
|
||||
{
|
||||
SqList L;
|
||||
L.r=new ElemType[MAXSIZE+1];
|
||||
L.length=0;
|
||||
Create_Sq(L);
|
||||
HeapSort(L);
|
||||
cout<<"排序后的结果为:"<<endl;
|
||||
show(L);
|
||||
}
|
||||
Reference in New Issue
Block a user