数据结构期末复习
1|0数据结构
1|1第四章 串
4.1 统计频数
#include <cstdio>
#include <iostream>
#include<string.h>
using namespace std;
void Count( char s[],int b[])
{ //统计串中的数字字符和大写字母的频度,并将结果存入数组b
/**************begin************/
for(int i = 0 ; i < strlen(s) ; i ++)
{
if(s[i] >= '0' && s[i] <= '9')
b[(int)s[i] -(int)'0' ] += 1;
else
b[10 + (int)s[i]-(int)'A'] += 1;
}
/**************end**************/
}
int main()
{ char s[255]; // 定义串s
cin>>s; //输入串s
int b[36]={0}; //定义数组b,初始化为0
Count(s,b);
//输出统计结果(只输出存在的字符,格式为 字符:频度),字符排列顺序按照ASCII码从小到大的顺序。
/**************begin************/
for(int i = 0 ; i < 36 ; i ++)
{
if(b[i] != 0 )
{
if(i >= 0 && i <= 9) cout << i ;
else printf("%c",'A' + i - 10);
cout << ":" << b[i] << endl;
}
}
/**************end**************/
return 0;
}
4.2 取子串
#include <cstdio>
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status;
#define MAXLEN 255
typedef struct{
char ch[MAXLEN+1]; //从1号下标开始存储串值
int length; //串的长度
}SString; //串的定长顺序存储结构
void InputStr(SString &s) //输入串
{
char str[MAXLEN];
int i;
cin>>str;
for (i=0;str[i]!='\0';i++)
s.ch[i+1]=str[i];
s.length=i;
}
void OutputStr(SString s) //输出串
{
for (int i=1;i<=s.length;i++)
cout<<s.ch[i];
}
Status SubString(SString s,SString &sub,int pos,int len){
//在串s的第pos位置开始取出len个字符,存入串sub,若成功,返回OK,否则返回ERROR
/********************begin********************/
if(pos + len - 1> s.length || pos <= 0 || len <= 0 || pos > s.length || len > s.length) return ERROR;
for(int i = pos, j = 1 ; i < pos + len ; i ++,j ++)
sub.ch[j] = s.ch[i];
sub.length = len;
return OK;
/********************end ********************/
}
int main()
{
SString s,sub;
int pos,len;
InputStr(s); //输入串s
cin>>pos;
cin>>len;
//调用取子串函数,并按要求输出。
/********************begin********************/
if(SubString(s,sub,pos,len)) OutputStr(sub);
else cout << "Error!";
/********************end ********************/
return 0;
}
4.3 kmp
#include <iostream>
using namespace std;
#define MAXLEN 255
typedef struct{
char ch[MAXLEN+1]; //从1号下标开始存储串值
int length; //串的长度
}SString; //串的定长顺序存储结构
void InputStr(SString &s) //输入串
{
char str[MAXLEN];
int i;
cin>>str;
for (i=0;str[i]!='\0';i++)
s.ch[i+1]=str[i];
s.length=i;
}
int Index_BF(SString s,SString t)
{ //在串s中查找串t的首次出现位置,如不存在,则返回0
/***************begin*************/
for(int i = 1 ; i <= s.length ; i ++)
{
int flag = 1 ;
int x = i;
for(int j = 1 ; j <= t.length ; j ++)
{
//cout << "j:" << j << endl;
if(s.ch[x++] != t.ch[j])
{
flag = 0 ;
break;
}
}
if(flag) return i;
}
return 0;
/***************end *************/
}
int main()
{
SString s,t;
InputStr(s); //输入串s
InputStr(t);
// cout << s.length << endl;
// cout << t.length << endl; //输入串t
cout<<Index_BF(s,t); //输出查找结果
return 0;
}
4.4 串的插入
#include <iostream>
using namespace std;
#define MAXLEN 255
typedef struct{
char ch[MAXLEN+1]; //从1号下标开始存储串值
int length; //串的长度
}SString; //串的定长顺序存储结构
void InputStr(SString &s) //输入串
{
char str[MAXLEN];
int i;
cin>>str;
for (i=0;str[i]!='\0';i++)
s.ch[i+1]=str[i];
s.length=i;
}
void OutputStr(SString s) //输出串
{
for (int i=1;i<=s.length;i++)
cout<<s.ch[i];
}
void InsertStr(SString &s,int pos, SString t)
{ //在串s的第pos位置插入串t,如pos不合法,则不插入
/***************begin*************/
if(pos <= 0 || pos > s.length + 1 || s.length + t.length > MAXLEN || pos + t.length > MAXLEN) return;
for(int i = s.length ,j = s.length + t.length ; i >= pos ; j--,i--)
{
s.ch[j] = s.ch[i];
//cout << "s" << j << " " << s.ch[j] <<" s" << i <<" "<< s.ch[i]<<endl;
}
for(int i = pos,j = 1 ; i < pos + t.length ; j++,i++)
{
s.ch[i] = t.ch[j];
//cout << "s" << i << " " << s.ch[i] <<" t" << j <<" "<< t.ch[j]<<endl;
}
s.length = s.length + t.length;
// cout << s.length;
// for (int i=1;i<=s.length;i++)
// cout<<i<<":"<<s.ch[i]<<endl;
return;
/***************end *************/
}
int main()
{
SString s,t;
int pos;
InputStr(s); //输入串s
cin>>pos; //输入插入位置
InputStr(t); //输入串t
InsertStr(s,pos,t); //调用插入函数
OutputStr(s); //输出串s
return 0;
}
1|2第五章 二叉树
5.1 二叉树的建立和遍历
#include<iostream>
#include<string.h>
using namespace std;
typedef char ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)
{//先序建立二叉树
/**************begin************/
char ch;
cin >> ch;
if(ch == '#') T = NULL;
else {
T = new BiTNode;//T是树的指针 new BiTNode 开辟一个BiTNode的指针
T->data = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return;
/**************end************/
}
void PreOrderTraverse(BiTree T)
{//二叉树的先序遍历
/**************begin************/
if(T){
cout << T->data ;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
/**************end************/
}
void InOrderTraverse(BiTree T)
{//二叉树的中序遍历
/**************begin************/
if(T){
InOrderTraverse(T->lchild);
cout << T->data ;
InOrderTraverse(T->rchild);
}
/**************end************/
}
void PostOrderTraverse(BiTree T)
{//二叉树的后序遍历
/**************begin************/
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout << T->data ;
}
/**************end************/
}
int main()
{
BiTree T;
CreateBiTree(T);
PreOrderTraverse(T);
cout<<endl;
InOrderTraverse(T);
cout<<endl;
PostOrderTraverse(T);
cout<<endl;
return 0;
}
5.2 统计分支个数
#include<iostream>
#include<string.h>
using namespace std;
typedef char ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)
{//先序建立二叉树
ElemType ch;
cin>>ch;
if(ch=='#')
T=NULL;
else
{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
int Count_leaf(BiTree T){
//统计叶子结点的数目
/**************begin************/
if(!T) return 0;
else return Count_leaf(T->lchild) + Count_leaf(T->rchild) + (((!T->lchild)&&(!T->rchild))?1:0);
/**************end************/
}
int Count_Sigle(BiTree T) {
//统计单分支结点的数目
/**************begin************/
if(!T) return 0;
return Count_Sigle(T->lchild) + Count_Sigle(T->rchild) + (((!T->lchild)&&(T->rchild))||((T->lchild)&&(!T->rchild))?1:0);
/**************end************/
}
int Count_Double(BiTree T) {
//统计双分支结点的数目
/**************begin************/
if(!T) return 0;
return Count_Double(T->lchild) + Count_Double(T->rchild) + (((T->lchild)&&(T->rchild))?1:0);
/**************end************/
}
int main()
{
BiTree T;
CreateBiTree(T);
cout<<Count_leaf(T)<<" "<<Count_Sigle(T)<<" "<<Count_Double(T)<<endl;
return 0;
}
5.3 高度计算
#include<iostream>
#include <string.h>
using namespace std;
typedef char ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)
{//先序建立二叉树
ElemType ch;
cin>>ch;
if(ch=='#')
T=NULL;
else
{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
int Depth(BiTree T)
{//二叉树高度的计算
/**************begin************/
if(!T) return 0;
else{
int m = Depth(T->lchild);
int n = Depth(T->rchild);
return m > n ? (m+1) : (n+1);
}
/**************end************/
}
int main()
{
BiTree T;
CreateBiTree(T);
cout<<Depth(T)<<endl;
return 0;
}
5.4 二叉树左右孩子交换
#include<iostream>
#include<cstring>
using namespace std;
typedef char ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)
{//先序建立二叉树
ElemType ch;
cin>>ch;
if(ch=='#')
T=NULL;
else
{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void ChangeRL(BiTree &T)
{//二叉树左右孩子的交换
/**************begin************/
BiTree t;
if(!T) return;
else{
t = T->lchild;
T->lchild = T->rchild;
T->rchild = t;
ChangeRL(T->lchild);
ChangeRL(T->rchild);
}
/**************end************/
}
void PreOrderTraverse(BiTree T)
{//先序遍历
if(T)
{
cout<<T->data;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
int main()
{
BiTree T;
CreateBiTree(T);
ChangeRL(T);
PreOrderTraverse(T);
cout<<endl;
return 0;
}
5.5 两个二叉树的相等判断
#include<iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)
{//先序建立二叉树
ElemType ch;
cin>>ch;
if(ch=='#')
T=NULL;
else
{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
int Compare(BiTree T1,BiTree T2)
{//判断两棵二叉树是否相等,不相等返回0,相等返回1
/**************begin************/
if(!T1 && !T2) return true;
if(!T1 || !T2) return false;
return T1->data == T2->data && Compare(T1->rchild,T2->rchild) && Compare(T1->lchild,T2->lchild);
/**************end************/
}
int main()
{
BiTree T1,T2;
CreateBiTree(T1);
CreateBiTree(T2);
if(!Compare(T1,T2))
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
return 0;
}
5.6 二叉树的层次遍历
#include<iostream>
#include<string.h>
using namespace std;
int flag;
#define OK 1
#define ERROR -1
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef char ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//链队列定义
typedef BiTree QElemType;
typedef struct QNode {
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct {
QueuePtr front;
QueuePtr rear;
}LinkQueue;
//队列基本操作
Status InitQueue (LinkQueue &Q){
//构造一个空队列
Q.front=Q.rear=new QNode;
if(!Q.front) return ERROR;
Q.front->next=NULL;
return OK;
}
Status QueueEmpty(LinkQueue Q){
//判断Q是否为空, 若为空,则输出TRUE,否则输出FALSE
if(Q.front==Q.rear)
return TRUE;
return FALSE;
}
Status EnQueue(LinkQueue &Q,QElemType e){
//将元素e入队列
QueuePtr p;
p=new QNode;
if(!p) return ERROR;
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
Status DeQueue(LinkQueue &Q,QElemType &e){
//将元素e出队列
QueuePtr p;
if(Q.front==Q.rear)
return ERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
delete p;
return OK;
}
void CreateBiTree(BiTree &T)
{//先序建立二叉树
ElemType ch;
cin>>ch;
if(ch=='#')
T=NULL;
else
{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
Status LevelOrder(BiTree T)//层次遍历二叉树
{
/**************begin************/
LinkQueue Q;
QElemType t;
InitQueue(Q);
if(T){
EnQueue(Q,T);
while(!QueueEmpty(Q)){
DeQueue(Q,t);
cout << t->data;
if(t->lchild) EnQueue(Q,t->lchild);
if(t->rchild) EnQueue(Q,t->rchild);
}
}
/**************end************/
}
int main()
{
BiTree T;
CreateBiTree(T);
LevelOrder(T);
cout<<endl;
return 0;
}
5.7 二叉树的WPL计算
#include<iostream>
using namespace std;
typedef struct BiTNode
{
int weight;
struct BiTNode *left,*right;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)
{//先序建立二叉树
int x;
cin>>x;
if(x == 0) T=NULL;
else
{
T=new BiTNode;
T->weight=x;
CreateBiTree(T->left);
CreateBiTree(T->right);
}
}
int WPL(BiTree &T,int d)
{//求二叉树T的带权路径长度
/**************begin************/
if(!T) return 0;
return ((!T->left)&&(!T->right)?T->weight*d:0) + WPL(T->right,d+1) + WPL(T->left,d+1);
/**************end************/
}
int main()
{
while(1)
{
BiTree T;
CreateBiTree(T);
if(!T) break;
int d=0; //调用时T指向二叉树的根结点,d为0
cout<<WPL(T,d)<<endl;
}
return 0;
}
1|3第六章 图
1|06.1 邻接矩阵
6.1.1 建立无向网的邻接矩阵
#include <cstdio>
#include <iostream>
using namespace std;
#define MaxInt 32767 //最大值
#define MVNum 20 //最大顶点数
typedef struct {
int vexnum,arcnum; //顶点数和边的数目
char vexs[MVNum]; //顶点向量
int arcs[MVNum][MVNum]; //邻接矩阵
}AMGraph;
int LovateVex(AMGraph G,char v){
int i;
for ( i=0; i<G.vexnum; i++)
if (G.vexs[i]==v) return i;
return -1;
}
void CreateUDN(AMGraph &G) //创建无向网的邻接矩阵
{/****************begin****************/
cin >> G.vexnum >> G.arcnum;
for(int i = 0 ; i < G.vexnum ; i++)
cin >> G.vexs[i];
for(int i = 0 ; i < G.vexnum ; i++)
for(int j = 0 ; j < G.vexnum ; j++)
G.arcs[i][j] = (i == j ? 0 : MaxInt);
for(int k = 0; k < G.arcnum ; k++){
char v1, v2;
int w;
cin >> v1 >> v2 >> w;
int i = LovateVex(G,v1), j = LovateVex(G,v2);
G.arcs[i][j] = w;
G.arcs[j][i] = w;
}
/******************end****************/
}
void PrintGraph(AMGraph G) //输出图的邻接矩阵
{
cout<<"图的邻接矩阵:";
for (int i=0;i<G.vexnum;i++)
{ cout<<endl;
for (int j=0;j<G.vexnum;j++){
if (G.arcs[i][j]==MaxInt)
printf(" ∞");
else
printf("%5d",G.arcs[i][j]);
}
}
}
int main()
{
AMGraph G;
CreateUDN(G);
PrintGraph(G);
return 0;
}
6.1.2 深度优先遍历
#include <iostream>
using namespace std;
#define MaxInt 32767 //最大值
#define MVNum 20 //最大顶点数
typedef struct {
int vexnum,arcnum; //顶点数和弧的数目
char vexs[MVNum]; //顶点向量
int arcs[MVNum][MVNum]; //邻接矩阵
}AMGraph;
int LocateVex(AMGraph G,char v){
int i;
for ( i=0; i<G.vexnum; i++)
if (G.vexs[i]==v) return i;
return -1;
}
void CreateDG(AMGraph &G)
{//创建有向图的邻接矩阵
/****************begin****************/
cin >> G.vexnum >> G.arcnum;
for(int i = 0 ; i < G.vexnum ; i++)
cin >> G.vexs[i];
for(int i = 0 ; i < G.vexnum ; i++)
for(int j = 0 ; j < G.vexnum ; j++)
G.arcs[i][j] = 0;
for(int k = 0; k < G.arcnum ; k++){
char v1, v2;
cin >> v1 >> v2;
int i = LocateVex(G,v1), j = LocateVex(G,v2);
G.arcs[i][j] = 1;
}
/****************end*****************/
}
void PrintGraph(AMGraph G) //输出图的邻接矩阵
{
cout<<"有向图的邻接矩阵:";
for (int i=0;i<G.vexnum;i++)
{ cout<<endl;
for (int j=0;j<G.vexnum;j++)
{
printf("%5d",G.arcs[i][j]);
}
}
}
//深度优先搜索DFS
bool visited[MVNum];
void DFS(AMGraph G,int v)
{//从顶点v开始对图进行深度优先遍历
/****************begin****************/
cout << " " << G.vexs[v] ;
visited[v] = true;
for(int i = 0 ; i < G.vexnum ; i ++)
{
if(!visited[i] && G.arcs[v][i] != 0) DFS(G,i);
}
/****************begin****************/
}
void DFSTraverse(AMGraph G)
{//图的深度优先遍历
/****************begin****************/
for(int v = 0 ; v < G.vexnum ; v++) visited[v] = false;
for(int v = 0 ; v < G.vexnum ; v ++)
if(!visited[v]) {
DFS(G,v);
cout << endl;
}
/****************end ****************/
}
int main()
{
AMGraph G;
CreateDG(G); //建立有向图的邻接矩阵
PrintGraph(G); //输出图的邻接矩阵
cout<<"\n图的深度优先序列:\n";
DFSTraverse(G);
return 0;
}
6.1.3 prime求最小生成树
#include <cstdio>
#include <iostream>
using namespace std;
#include "graph.h" //图的定义、无向网的建立以及输出函数
typedef struct{
char adjvex;
int lowcost;
}node;
node closedge[MVNum]; //定义待选边辅助数组
int Min(AMGraph G)
{
//从待选边辅助数组closeedge中选择最小边closedge[k],返回k
int k = 0;
while (closedge[k].lowcost == 0)
k++;
int min = closedge[k].lowcost;
for (int i = k + 1; i < G.vexnum; i++)
{
if (closedge[i].lowcost != 0 && closedge[i].lowcost < min)
{
min = closedge[i].lowcost;
k = i;
}
}
return k;
}
int MiniSpanTree(AMGraph G, char u)
{
//从顶点u出发构造最小生成树T,输出T的各条边,函数返回T的代价
int uIndex = LocateVex(G, u);
for (int i = 0; i < G.vexnum; i++)
{
if (i != uIndex)
{
closedge[i].adjvex = u;
closedge[i].lowcost = G.arcs[uIndex][i];
}
}
closedge[uIndex].lowcost = 0;
cout << endl;
int MSTcost = 0;
for (int i = 1; i < G.vexnum; i++)
{
int k = Min(G);
cout <<"(" <<closedge[k].adjvex <<"," << G.vexs[k] << ") " << closedge[k].lowcost << endl;
MSTcost += closedge[k].lowcost;
closedge[k].lowcost = 0;
for (int j = 0; j < G.vexnum; j++)
{
if (G.arcs[k][j] < closedge[j].lowcost)
{
closedge[j].adjvex = G.vexs[k];
closedge[j].lowcost = G.arcs[k][j];
}
}
}
return MSTcost;
}
int main()
{
AMGraph G;
char u;
int MSTcost;
CreateUDN(G); //建立无向网的邻接矩阵
cin>>u; //输入起始顶点
PrintGraph(G); //输出无向网
cout<<"\n\n最小生成树的边:";
MSTcost=MiniSpanTree(G,u); // 从顶点u出发构造最小生成树T
cout<<"\n最小生成树的代价:\n"<<MSTcost;
return 0;
}
6.1.4 Dijkstra算法求解单源点最短路径
#include<bits/stdc++.h>
using namespace std;
#include "graph.h" //图的定义、 有向网的建立以及输出函数
void ShortestPath_DIJ(AMGraph G, int v0) {
vector<int> dist(G.vexnum, MaxInt);
vector<bool> visited(G.vexnum, false);
dist[v0] = 0;
for (int i = 0; i < G.vexnum; ++i) {
int u = -1;
for (int j = 0; j < G.vexnum; ++j) {
if (!visited[j] && (u == -1 || dist[j] < dist[u])) {
u = j;
}
}
visited[u] = true;
for (int v = 0; v < G.vexnum; ++v) {
if (!visited[v] && G.arcs[u][v] != MaxInt) {
if (dist[u] + G.arcs[u][v] < dist[v]) {
dist[v] = dist[u] + G.arcs[u][v];
}
}
}
}
vector<tuple<int, int, int>> paths;
for (int i = 0; i < G.vexnum; ++i) {
if (i != v0 && dist[i] != MaxInt) {
paths.push_back(make_tuple(v0, i, dist[i]));
}
}
sort(paths.begin(), paths.end(), [&](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {
return get<2>(a) < get<2>(b);
});
for (const auto& path : paths) {
cout << G.vexs[get<0>(path)] << "-->" << G.vexs[get<1>(path)] << " " << get<2>(path) << endl;
}
}
int main()
{
AMGraph G;
char u;
CreateDN(G); //建立有向网的邻接矩阵
cin>>u; //输入源点
PrintGraph(G); //输出有向网的邻接矩阵
int v0=LocateVex(G,u);
cout<<"\n从顶点"<<u<<"到图中其他顶点的最短路径:\n" ;
ShortestPath_DIJ(G,v0); //从顶点v0开始,应用dijkstra算法求最短路径
return 0;
}
1|06.2 邻接表
6.2.1 图的建立
#include <cstdio>
#include <iostream>
using namespace std;
#define MVNum 20 //最大顶点数
typedef struct ArcNode{ //边结点
int adjvex; //邻接点的位置
struct ArcNode *nextarc; //指向下一条边的指针
}ArcNode;
typedef struct VNode{ //表头结点(顶点信息)
char data; //顶点值
ArcNode *firstarc; //指向第一条依附该顶点的边的指针
}VNode;
typedef struct {
int vexnum; //图的顶点数
int arcnum; //图的边数
VNode vertices[MVNum]; //顶点向量表
}ALGraph; //邻接表
int LocateVex(ALGraph G,char v)
{//在顶点向量表中查找顶点v,如果找到,则返回顶点在图中的位置,否则返回-1
for (int i=0;i<G.vexnum ;i++)
if ( G.vertices[i].data==v ) return i;
return -1;
}
void CreateUDG(ALGraph &G)
{//建立无向图的邻接表 , 对每一条边(i,j),按照头插法,分别将表结点插入i表和j表
/******************begin*****************/
int i,j,k;
char v1,v2;
ArcNode *p,*q;
cin >> G.vexnum >> G.arcnum;
for(i = 0 ; i < G.vexnum ; i ++)
{
cin >> G.vertices[i].data;
G.vertices[i].firstarc = NULL;
}
for(k = 0 ; k < G.arcnum ; k ++)
{
cin >> v1 >> v2;
i = LocateVex(G,v1);
j = LocateVex(G,v2);
p = new ArcNode;
p->adjvex = j;
p->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p;
q = new ArcNode;
q->adjvex = i;
q->nextarc = G.vertices[j].firstarc;
G.vertices[j].firstarc = q;
}
/******************end ******************/
}
void PrintGraph(ALGraph G) //输出图中每个点的邻接点
{
ArcNode *p;
for (int i=0;i<G.vexnum;i++)
{
printf("\n%2c邻接到:",G.vertices[i].data);
for (p=G.vertices[i].firstarc; p ;p=p->nextarc)
{
int j=p->adjvex;
printf("%2c",G.vertices[j].data);
}
}
}
int main()
{ ALGraph G;
CreateUDG(G); //建立无向图的邻接表
PrintGraph(G); //输出图的邻接表
return 0;
}
6.2.2 计算顶点的出度和入度
#include <cstdio>
#include <iostream>
using namespace std;
#define MVNum 20 //最大顶点数
typedef struct ArcNode{ //边结点
int adjvex; //邻接点的位置
struct ArcNode *nextarc; //指向下一条边的指针
}ArcNode;
typedef struct VNode{ //表头结点(顶点信息)
char data; //顶点值
ArcNode *firstarc; //指向第一条依附该顶点的边的指针
}VNode;
typedef struct {
int vexnum; //图的顶点数
int arcnum; //图的边数
VNode vertices[MVNum]; //顶点向量表
}ALGraph; //邻接表
int LocateVex(ALGraph G,char v)
{//在顶点向量表中查找顶点v,如果找到,则返回顶点在图中的位置,否则返回-1
for (int i=0;i<G.vexnum ;i++)
if ( G.vertices[i].data==v ) return i;
return -1;
}
void CreateDG(ALGraph &G)
{//建立有向图的邻接表 , 对每一条边<i,j>,按照头插法,分别将表结点插入i表
int i,j,k;
char v1,v2;
ArcNode *p;
cin>>G.vexnum>>G.arcnum; //输入图的顶点数和边数
for (i=0;i<G.vexnum;i++) //初始化顶点向量表
{
cin>>G.vertices[i].data; //输入顶点信息
G.vertices[i].firstarc=NULL; //初始化每个顶点的邻接表
}
for (k=0;k<G.arcnum;k++) //依次输入图的每条边
{
cin>>v1>>v2;
i=LocateVex(G,v1);
j=LocateVex(G,v2);
p=new ArcNode;
p->adjvex=j;
p->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p;
}
}
void PrintGraph(ALGraph G) //输出图中每个点的邻接点
{
ArcNode *p;
for (int i=0;i<G.vexnum;i++)
{
printf("\n%2c邻接到:",G.vertices[i].data);
for (p=G.vertices[i].firstarc; p ;p=p->nextarc)
{
int j=p->adjvex;
printf("%2c",G.vertices[j].data);
}
}
}
void FindOutdegree(ALGraph G,int outdegree[])
{ //计算每个顶点的出度,存入数组outdegree
/******************begin*****************/
for(int i = 0 ; i < G.vexnum ; i++){
outdegree[i] = 0;
ArcNode *p = G.vertices[i].firstarc;
while(p){
outdegree[i]++;
p = p->nextarc;
}
}
/******************end *****************/
}
void FindIndegree(ALGraph G,int indegree[])
{ //计算每个顶点的入度,存入数组indegree
/******************begin*****************/
for(int i = 0 ; i < G.vexnum ; i++){
indegree[i] = 0;
for(int j = 0 ; j < G.vexnum ; j++)
{
ArcNode *p = G.vertices[j].firstarc;
while(p){
if(p->adjvex == i){
indegree[i]++;
break;
}
p = p->nextarc;
}
}
}
/******************end *****************/
}
int main()
{ ALGraph G;
int indegree[MVNum],outdegree[MVNum];
CreateDG(G); //建立有向图的邻接表
PrintGraph(G); //输出图的邻接表
FindOutdegree(G,outdegree); //计算每个顶点的出度
cout<<"\n 顶点的出度:";
for (int i=0;i<G.vexnum;i++)
printf("%2d",outdegree[i]);
FindIndegree(G,indegree); //计算每个顶点的入度
cout<<"\n 顶点的入度:";
for (int i=0;i<G.vexnum;i++)
printf("%2d",indegree[i]) ;
return 0;
}
6.2.3 图的广度优先遍历
#include <cstdio>
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status;
typedef int QElemType;
#define MAX_QSIZE 5 // 最大队列长度+1
//循环队列的定义以及基本算法(初始化、入队、出队、判队空)
struct SqQueue
{
QElemType *base; // 初始化的动态分配存储空间
int front; // 头指针,若队列不空,指向队列头元素
int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
};
// 循环队列的基本操作(9个)
Status InitQueue(SqQueue &Q)
{ // 构造一个空队列Q
/********** Begin **********/
Q.base = new QElemType[MAX_QSIZE];
if(!Q.base) return ERROR;
Q.front = Q.rear = 0;
return OK;
/********** End **********/
}
Status QueueEmpty(SqQueue Q)
{ // 若队列Q为空队列,则返回TRUE;否则返回FALSE
/********** Begin **********/
return (Q.front == Q.rear);
/********** End **********/
}
Status EnQueue(SqQueue &Q,QElemType e)
{ // 插入元素e为Q的新的队尾元素
/********** Begin **********/
if((Q.rear+1)%MAX_QSIZE == Q.front) return ERROR;
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1)%MAX_QSIZE;
//cout << endl << "Q.front=" << Q.front << " " <<"Q.rear="<<Q.rear<< endl;
return OK;
/********** End **********/
}
Status DeQueue(SqQueue &Q,QElemType &e)
{ // 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
/********** Begin **********/
if(Q.front == Q.rear) return ERROR;
e = Q.base[Q.front];
Q.front = (Q.front+1)%MAX_QSIZE;
/********** End **********/
}
#define MVNum 20 //最大顶点数
typedef struct ArcNode{ //边结点
int adjvex; //邻接点的位置
struct ArcNode *nextarc; //指向下一条边的指针
}ArcNode;
typedef struct VNode{ //表头结点(顶点信息)
char data; //顶点值
ArcNode *firstarc; //指向第一条依附该顶点的边的指针
}VNode;
typedef struct {
int vexnum; //图的顶点数
int arcnum; //图的边数
VNode vertices[MVNum]; //顶点向量表
}ALGraph; //邻接表
int LocateVex(ALGraph G,char v)
{//在顶点向量表中查找顶点v,如果找到,则返回顶点在图中的位置,否则返回-1
for (int i=0;i<G.vexnum ;i++)
if ( G.vertices[i].data==v ) return i;
return -1;
}
void CreateUDG(ALGraph &G)
{//建立无向图的邻接表 , 对每一条边(i,j),按照头插法,分别将表结点插入i表和j表
int i,j,k;
char v1,v2;
ArcNode *p,*q;
cin>>G.vexnum>>G.arcnum; //输入图的顶点数和边数
for (i=0;i<G.vexnum;i++) //初始化顶点向量表
{
cin>>G.vertices[i].data; //输入顶点信息
G.vertices[i].firstarc=NULL; //初始化每个顶点的邻接表
}
for (k=0;k<G.arcnum;k++) //依次输入图的每条边
{
cin>>v1>>v2;
i=LocateVex(G,v1);
j=LocateVex(G,v2);
p=new ArcNode;
p->adjvex=j;
p->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p;
q=new ArcNode;
q->adjvex=i;
q->nextarc=G.vertices[j].firstarc;
G.vertices[j].firstarc=q;
}
}
void PrintGraph(ALGraph G) //输出图中每个点的邻接点
{
ArcNode *p;
for (int i=0;i<G.vexnum;i++)
{
printf("\n%2c邻接到:",G.vertices[i].data);
for (p=G.vertices[i].firstarc; p ;p=p->nextarc)
{
int j=p->adjvex;
printf("%2c",G.vertices[j].data);
}
}
}
bool visited[MVNum]; //定义访问标记数组
void BFS(ALGraph G,int v)
{ //从顶点v出发,对图进行广度优先遍历
SqQueue Q; //定义队列Q
InitQueue(Q); //将队列Q初始化为空队列
/******************begin*****************/
cout << ' ' << G.vertices[v].data;//访问节点
EnQueue(Q,v);//节点入队
visited[v] = true;//标记
while(!QueueEmpty(Q)){
DeQueue(Q,v);
ArcNode *p = G.vertices[v].firstarc;
//遍历v的所有出边
while(p){
int u = p->adjvex;
if(!visited[u]){
//如果没有遍历过 就输出 入队
cout << ' ' << G.vertices[u].data;
visited[u] = true;
EnQueue(Q,u);
}
p = p->nextarc;
}
}
/******************end******************/
}//BFS
void BFSTraverse(ALGraph G){
int v;
for (v=0;v<G.vexnum;v++) //初始化每个顶点的访问标记为false
visited[v]=false;
for (v=0;v<G.vexnum;v++)
{
if (!visited[v])
{
cout<<endl;
BFS(G,v); //对未访问的顶点v,调用BFS,进行广度优先搜索
}
}
}//BFSTraverse
int main()
{ ALGraph G;
CreateUDG(G); //建立无向图的邻接表
PrintGraph(G); //输出图的邻接表
cout<<"\n 图的广度优先序列:";
BFSTraverse(G); //广度优先遍历
return 0;
}
6.2.4 AOV网的拓扑排序
#include <cstdio>
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status;
#include "stack.h"//顺序栈的定义和基本函数的定义
#include "graph.h"//图的邻接表定义,以及图的建立
void FindIndegree(ALGraph G, int indegree[])
{ //计算每个顶点的入度,存入数组indegree
for (int i = 0; i < G.vexnum; i++)
indegree[i] = 0;
for (int i = 0; i < G.vexnum; i++)
{
ArcNode *p = G.vertices[i].firstarc;
while (p)
{
int j = p->adjvex;
indegree[j]++;
p = p->nextarc;
}
}
}
Status TopologicalSort(ALGraph G, int topo[])
{
int indegree[MVNum];
SqStack S;
InitStack(S);
FindIndegree(G, indegree);
for (int i = 0; i < G.vexnum; i++)
{
if (indegree[i] == 0)
{
Push(S, i);
}
}
int count = 0;
while (!StackEmpty(S))
{
Pop(S, topo[count++]);
ArcNode *p = G.vertices[topo[count - 1]].firstarc;
while (p)
{
indegree[p->adjvex]--;
if (indegree[p->adjvex] == 0)
{
Push(S, p->adjvex);
}
p = p->nextarc;
}
}
if (count != G.vexnum)
{
return ERROR;
}
return OK;
}
int main()
{ ALGraph G;
int topo[MVNum];
CreateDG(G); //建立有向图的邻接表
PrintGraph(G); //输出图的邻接表
if (TopologicalSort(G,topo)==ERROR) //拓扑排序
cout<<"\n 图中有环,拓扑排序失败!";
else{
cout<<"\n 拓扑序列:";
for (int i=0;i<G.vexnum;i++)
printf("%2c",G.vertices[topo[i]].data);
}
return 0;
}
1|4第七章 查找
7.1 顺序查找
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*************************************************************
顺序查找 头文件
**************************************************************/
#define MAXSIZE 100
typedef int KeyType; /*关键字类型*/
typedef struct
{
KeyType key;
/*InfoType otherinfo;*/
}RedType; /*记录类型*/
typedef struct
{
RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
int length;
}SSTable; /*静态查找表的类型定义*/
/*******函数声明*******/
void SSTableInput(SSTable &L); /*输入若干记录的关键字,存放到静态查找表L中*/
void SSTableOutput(SSTable L); /*输出静态查找表L中各记录的关键字*/
int Search_Seq(SSTable L, KeyType key); /*顺序查找*/
/*************************************************************
顺序查找 实现文件
**************************************************************/
int Search_Seq(SSTable L, KeyType key)
{
for (int i = 1; i <= L.length; i++) {
if (L.r[i].key == key) {
return i;
}
}
return 0;
}
void SSTableInput(SSTable &L) /*输入若干记录的关键字,存放到静态查找表L中*/
{
int i=1; KeyType x;
scanf("%d",&x);
while(x!=-1)
{
L.r[i++].key=x; scanf("%d",&x);
}
L.length=i-1;
}
void SSTableOutput(SSTable L) /*输出静态查找表L中各记录的关键字*/
{
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.r[i].key);
printf("\n");
}
int main()
{
SSTable L; KeyType x;int loc;
SSTableInput(L);/*输入一组记录的关键字,存放到静态查找表L中*/
scanf("%d",&x); /*输入待查找的关键字*/
SSTableOutput(L);/*输出静态查找表L中各记录的关键字*/
loc=Search_Seq(L,x);/*采用顺序查找法,在表L中查找其关键字等于x的记录,并返回该记录在表中的位置*/
if(loc==0) printf("not find!\n");
else printf("%d\n",loc);/*输出关键字等于x的记录在表中的位置*/
return 0;
}
7.2 折半查找
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*************************************************************
折半查找 头文件
**************************************************************/
#define MAXSIZE 100
typedef int KeyType; /*关键字类型*/
typedef struct
{
KeyType key;
/*InfoType otherinfo;*/
}RedType; /*记录类型*/
typedef struct
{
RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
int length;
}SSTable; /*静态查找表的类型定义*/
/*******函数声明*******/
void SSTableInput(SSTable &L); /*输入若干记录的关键字,存放到静态查找表L中*/
void SSTableOutput(SSTable L); /*输出静态查找表L中各记录的关键字*/
int Search_Bin(SSTable L, KeyType key); /*折半查找*/
/*************************************************************
折半查找 实现文件
**************************************************************/
int Search_Bin(SSTable L, KeyType key)/*在递增有序的顺序表L中折半查找其关键字等于key的记录*/
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
int low = 1;
int high = L.length;
while (low <= high) {
int mid = (low + high) / 2;
if (L.r[mid].key == key) {
return mid;
} else if (L.r[mid].key < key) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return 0;
/********** End **********/
}
void SSTableInput(SSTable &L) /*输入若干记录的关键字,存放到静态查找表L中*/
{
int i=1; KeyType x;
scanf("%d",&x);
while(x!=-1)
{
L.r[i++].key=x; scanf("%d",&x);
}
L.length=i-1;
}
void SSTableOutput(SSTable L) /*输出静态查找表L中各记录的关键字*/
{
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.r[i].key);
printf("\n");
}
int main()
{
SSTable L; KeyType x;int loc;
SSTableInput(L);/*按递增或递减的顺序输入一组记录的关键字,存放到静态查找表L中*/
scanf("%d",&x); /*输入待查找的关键字*/
SSTableOutput(L);/*输出静态查找表L中各记录的关键字*/
loc=Search_Bin(L,x);/*采用折半查找法,在表L中查找其关键字等于x的记录,并返回该记录在表中的位置*/
if(loc==0) printf("not find!\n");
else printf("%d\n",loc);/*输出关键字等于x的记录在表中的位置*/
return 0;
}
7.3 二叉排序树的查找
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*************************************************************
二叉排序树的查找 头文件
**************************************************************/
#define MAXSIZE 100
typedef int KeyType; /*关键字类型*/
typedef struct
{
KeyType key;
/*InfoType otherinfo;*/
}RedType; /*记录类型*/
typedef struct BiTNode
{
RedType data;
struct BiTNode *lchild,*rchild;
}BiTNode, *BiTree; /*动态查找表的二叉链表存储表示*/
/*******函数声明*******/
BiTree Search_BST(BiTree T, KeyType key, BiTree &parent); /*二叉排序树的查找*/
void Insert_BST(BiTree &T, RedType r); /*二叉排序树的插入*/
void Create_BST(BiTree &T); /*二叉排序树的构造*/
void PreOrder(BiTree bt); /*先序遍历*/
void InOrder(BiTree bt); /*中序遍历*/
/*************************************************************
二叉排序树的查找 实现文件
**************************************************************/
BiTree Search_BST(BiTree T, KeyType key, BiTree &parent)
{
BiTree p = T;
parent = NULL;
while (p != NULL && p->data.key != key)
{
parent = p;
if (key < p->data.key)
p = p->lchild;
else
p = p->rchild;
}
return p;
}
void Insert_BST(BiTree &T, RedType r)/*若二叉排序树T中没有关键字为r.key的记录,则插入*/
{
BiTree p,q,parent;
parent=NULL;
p=Search_BST(T,r.key,parent); /*查找*/
if(p) printf("BST中有结点r,无需插入\n");
else
{
p=parent;
q=(BiTNode *)malloc(sizeof(BiTNode)); q->data=r; q->lchild=q->rchild=NULL;
if(T==NULL) T=q; /*若T为空,则q为新的根*/
else if(r.key<p->data.key) p->lchild=q;
else p->rchild=q;
}
}
void Create_BST(BiTree &T ) /*二叉排序树的构造*/
{/*输入若干记录的关键字(以-1标志结束),生成一棵BST,采用二叉链表存储,返回其根指针T*/
RedType r;
T=NULL; /*建空树*/
scanf("%d",&r.key);
while(r.key!=-1)
{
Insert_BST(T, r);
scanf("%d",&r.key);
}
}
void PreOrder(BiTree bt) /*先序遍历*/
{
if(bt)
{
printf("%d ",bt->data.key);
PreOrder(bt->lchild);
PreOrder(bt->rchild);
}
}
void InOrder(BiTree bt) /*中序遍历*/
{
if(bt)
{
InOrder(bt->lchild);
printf("%d ",bt->data.key);
InOrder(bt->rchild);
}
}
int main()
{
BiTree T; KeyType x;BiTree parent,loc;
Create_BST(T);/*输入一组记录的关键字,存入二叉排序树T中,即建立一棵二叉排序树T*/
scanf("%d",&x); /*输入待查找的关键字*/
printf("PreOrder:");
PreOrder(T);printf("\n");/*对二叉排序树T进行先序遍历*/
printf("InOrder:");
InOrder(T);printf("\n"); /*对二叉排序树T进行中序遍历*/
loc=Search_BST(T,x,parent); /*在二叉排序树T上查找其关键字等于x的记录结点。若找到,返回该结点指针,parent指向其双亲。*/
if(loc==NULL) printf("not find!\n");
else printf("%d\n",parent->data.key);/*输出关键字等于x的结点的双亲结点的关键字*/
return 0;
}
1|5第八章 排序
8.1 直接插入排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*************************************************************
直接插入排序 头文件
**************************************************************/
#define MAXSIZE 100
typedef int KeyType; /*关键字类型*/
typedef struct
{
KeyType key;
/*InfoType otherinfo;*/
}RedType; /*记录类型*/
typedef struct
{
RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
int length; /*length存放表长*/
}SeqList; /*顺序表类型*/
/*******函数声明*******/
void SeqListInput(SeqList &L); /*输入若干记录的关键字,存放到顺序表L中*/
void SeqListOutput(SeqList L); /*输出顺序表L中各记录的关键字*/
void InsertSort(SeqList &L); /*直接插入排序*/
void ShellInsert(SeqList &L, int d); /*对顺序表L作一趟增量为d的希尔插入排序*/
void ShellSort(SeqList &L); /*希尔排序*/
void QuickSort(SeqList &L, int low, int high); /*对顺序表L的子序列L.r[low…high]作快速排序*/
void HeapAdjust(SeqList &L, int low, int high);/*调整L.r[low].key,使L.r[low..high]成为一个新大顶堆。*/
void HeapSort(SeqList &L); /*堆排序*/
/*************************************************************
直接插入排序 实现文件
**************************************************************/
void InsertSort(SeqList &L) /*直接插入排序*/
{
int i, j;
for (i = 2; i <= L.length; i++)
{
RedType temp = L.r[i];
j = i - 1;
while (j > 0 && temp.key < L.r[j].key)
{
L.r[j + 1] = L.r[j];
j--;
}
L.r[j + 1] = temp;
if(i <= 4)
for (int k = 1; k <= L.length; k++)
{
printf("%d ", L.r[k].key);
}
if(i <= 4) printf("\n");
}
}
void SeqListInput(SeqList &L) /*输入若干记录的关键字,存放到顺序表L中*/
{
int i=1; KeyType x;
scanf("%d",&x);
while(x!=-1)
{
L.r[i++].key=x; scanf("%d",&x);
}
L.length=i-1;
}
void SeqListOutput(SeqList L) /*输出顺序表L中各记录的关键字*/
{
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.r[i].key);
printf("\n");
}
int main()
{
SeqList L;
SeqListInput(L);/*输入一组记录的关键字,存放到顺序表L中*/
//SeqListOutput(L);/*输出排序之前的关键字序列*/
InsertSort(L); /*进行直接插入排序*/
SeqListOutput(L);/*输出排序之后的关键字序列*/
return 0;
}
8.2 希尔排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*************************************************************
希尔排序 头文件
**************************************************************/
#define MAXSIZE 100
typedef int KeyType; /*关键字类型*/
typedef struct
{
KeyType key;
/*InfoType otherinfo;*/
}RedType; /*记录类型*/
typedef struct
{
RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
int length; /*length存放表长*/
}SeqList; /*顺序表类型*/
/*******函数声明*******/
void SeqListInput(SeqList &L); /*输入若干记录的关键字,存放到顺序表L中*/
void SeqListOutput(SeqList L); /*输出顺序表L中各记录的关键字*/
void InsertSort(SeqList &L); /*直接插入排序*/
void ShellInsert(SeqList &L, int d); /*对顺序表L作一趟增量为d的希尔插入排序*/
void ShellSort(SeqList &L); /*希尔排序*/
void QuickSort(SeqList &L, int low, int high); /*对顺序表L的子序列L.r[low…high]作快速排序*/
void HeapAdjust(SeqList &L, int low, int high);/*调整L.r[low].key,使L.r[low..high]成为一个新大顶堆。*/
void HeapSort(SeqList &L); /*堆排序*/
/*************************************************************
希尔排序 实现文件
**************************************************************/
void ShellInsert(SeqList &L, int d)
{
for (int i = d + 1; i <= L.length; i++)
{
if (L.r[i].key < L.r[i - d].key)
{
L.r[0] = L.r[i]; // 备份待插入的记录
int j;
for (j = i - d; j > 0 && L.r[0].key < L.r[j].key; j -= d)
{
L.r[j + d] = L.r[j];
}
L.r[j + d] = L.r[0]; // 插入到正确位置
}
}
}
void ShellSort(SeqList &L) /*希尔排序*/
{
int d;
d=L.length/2;
while(d!=0) /*调用一趟增量为d的希尔插入排序*/
{
ShellInsert(L,d); d=d/2;
}
}
void SeqListInput(SeqList &L) /*输入若干记录的关键字,存放到顺序表L中*/
{
int i=1; KeyType x;
scanf("%d",&x);
while(x!=-1)
{
L.r[i++].key=x; scanf("%d",&x);
}
L.length=i-1;
}
void SeqListOutput(SeqList L) /*输出顺序表L中各记录的关键字*/
{
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.r[i].key);
printf("\n");
}
int main()
{
SeqList L;
SeqListInput(L);/*输入一组记录的关键字,存放到顺序表L中*/
SeqListOutput(L);/*输出排序之前的关键字序列*/
ShellSort(L); /*进行希尔排序*/
SeqListOutput(L);/*输出排序之后的关键字序列*/
return 0;
}
8.3 快速排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*************************************************************
快速排序 头文件
**************************************************************/
#define MAXSIZE 100
typedef int KeyType; /*关键字类型*/
typedef struct
{
KeyType key;
/*InfoType otherinfo;*/
}RedType; /*记录类型*/
typedef struct
{
RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
int length; /*length存放表长*/
}SeqList; /*顺序表类型*/
/*******函数声明*******/
void SeqListInput(SeqList &L); /*输入若干记录的关键字,存放到顺序表L中*/
void SeqListOutput(SeqList L); /*输出顺序表L中各记录的关键字*/
void InsertSort(SeqList &L); /*直接插入排序*/
void ShellInsert(SeqList &L, int d); /*对顺序表L作一趟增量为d的希尔插入排序*/
void ShellSort(SeqList &L); /*希尔排序*/
void QuickSort(SeqList &L, int low, int high); /*对顺序表L的子序列L.r[low…high]作快速排序*/
void HeapAdjust(SeqList &L, int low, int high);/*调整L.r[low].key,使L.r[low..high]成为一个新大顶堆。*/
void HeapSort(SeqList &L); /*堆排序*/
/*************************************************************
快速排序 实现文件
**************************************************************/
void QuickSort(SeqList &L, int low, int high)
{
if (low < high)
{
int i = low, j = high;
L.r[0] = L.r[low]; // 设置基准
while (i < j)
{
while (i < j && L.r[j].key >= L.r[0].key)
j--;
if (i < j)
L.r[i++] = L.r[j];
while (i < j && L.r[i].key <= L.r[0].key)
i++;
if (i < j)
L.r[j--] = L.r[i];
}
L.r[i] = L.r[0]; // 基准归位
QuickSort(L,low,i-1);/*对左半区L.r[low..i-1]进行快速排序*/
QuickSort(L,i+1,high);/*对右半区L.r[i+1..high]进行快速排序*/
}
}
void SeqListInput(SeqList &L) /*输入若干记录的关键字,存放到顺序表L中*/
{
int i=1; KeyType x;
scanf("%d",&x);
while(x!=-1)
{
L.r[i++].key=x; scanf("%d",&x);
}
L.length=i-1;
}
void SeqListOutput(SeqList L) /*输出顺序表L中各记录的关键字*/
{
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.r[i].key);
printf("\n");
}
int main()
{
SeqList L;
SeqListInput(L);/*输入一组记录的关键字,存放到顺序表L中*/
SeqListOutput(L);/*输出排序之前的关键字序列*/
QuickSort(L,1,L.length); /*进行快速排序*/
SeqListOutput(L);/*输出排序之后的关键字序列*/
return 0;
}
8.4 堆排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*************************************************************
堆排序 头文件
**************************************************************/
#define MAXSIZE 100
typedef int KeyType; /*关键字类型*/
typedef struct
{
KeyType key;
/*InfoType otherinfo;*/
}RedType; /*记录类型*/
typedef struct
{
RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
int length; /*length存放表长*/
}SeqList; /*顺序表类型*/
/*******函数声明*******/
void SeqListInput(SeqList &L); /*输入若干记录的关键字,存放到顺序表L中*/
void SeqListOutput(SeqList L); /*输出顺序表L中各记录的关键字*/
void InsertSort(SeqList &L); /*直接插入排序*/
void ShellInsert(SeqList &L, int d); /*对顺序表L作一趟增量为d的希尔插入排序*/
void ShellSort(SeqList &L); /*希尔排序*/
void QuickSort(SeqList &L, int low, int high); /*对顺序表L的子序列L.r[low…high]作快速排序*/
void HeapAdjust(SeqList &L, int low, int high);/*调整L.r[low].key,使L.r[low..high]成为一个新大顶堆。*/
void HeapSort(SeqList &L); /*堆排序*/
/*************************************************************
堆排序 实现文件
**************************************************************/
void HeapAdjust(SeqList &L, int low, int high)
{
int i = low, j = 2 * i; // 初始化,j指向左孩子
L.r[0] = L.r[low]; // 记录调整前的堆顶元素
while (j <= high)
{
// 比较左右孩子大小,将j指向较大的孩子
if (j < high && L.r[j].key < L.r[j + 1].key)
j++;
// 比较堆顶元素和较大孩子的大小
if (L.r[0].key < L.r[j].key)
{
L.r[i] = L.r[j]; // 将较大孩子上移
i = j; // 更新i为新的调整位置
j = 2 * i; // 更新j为左孩子
}
else
{
break; // 调整结束
}
}
L.r[i] = L.r[0]; // 将堆顶元素放入最终位置
}
void HeapSort(SeqList &L) /*堆排序*/
{
int i;
for(i=L.length/2;i>0;i--)/*从最后一个分支结点(编号为L.length/2)开始调整,建立初始堆*/
HeapAdjust(L,i,L.length);
for(i=L.length;i>1;i--)
{
L.r[0]=L.r[1];L.r[1]=L.r[i];L.r[i]=L.r[0];/*将堆顶L.r[1]和当前最后一个记录L.r[i]交换*/
HeapAdjust(L,1,i-1);/*将剩余记录L.r[1..i-1]重新调整为堆*/
}
}
void SeqListInput(SeqList &L) /*输入若干记录的关键字,存放到顺序表L中*/
{
int i=1; KeyType x;
scanf("%d",&x);
while(x!=-1)
{
L.r[i++].key=x; scanf("%d",&x);
}
L.length=i-1;
}
void SeqListOutput(SeqList L) /*输出顺序表L中各记录的关键字*/
{
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.r[i].key);
printf("\n");
}
int main()
{
SeqList L;
SeqListInput(L);/*输入一组记录的关键字,存放到顺序表L中*/
SeqListOutput(L);/*输出排序之前的关键字序列*/
HeapSort(L); /*进行堆排序*/
SeqListOutput(L);/*输出排序之后的关键字序列*/
return 0;
}
8.5 冒泡排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*************************************************************
冒泡排序 头文件
**************************************************************/
#define MAXSIZE 100
typedef int KeyType; /*关键字类型*/
typedef struct
{
KeyType key;
/*InfoType otherinfo;*/
}RedType; /*记录类型*/
typedef struct
{
RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
int length; /*length存放表长*/
}SeqList; /*顺序表类型*/
/*******函数声明*******/
void SeqListInput(SeqList &L); /*输入若干记录的关键字,存放到顺序表L中*/
void SeqListOutput(SeqList L); /*输出顺序表L中各记录的关键字*/
void BubbleSort(SeqList &L); /*冒泡排序*/
/*************************************************************
冒泡排序 实现文件
**************************************************************/
void BubbleSort(SeqList &L)
{
int i, j;
for (i = 1; i <= L.length - 1; i++)
{
// 输出前三趟排序后的关键字序列
if (i <= 4 && i >= 2)
{
for (j = 1; j <= L.length; j++)
printf("%d ", L.r[j].key);
printf("\n");
}
for (j = 1; j <= L.length - i; j++)
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
if (L.r[j].key > L.r[j + 1].key)
{
// 交换两个元素
RedType temp = L.r[j];
L.r[j] = L.r[j + 1];
L.r[j + 1] = temp;
}
/********** End **********/
}
}
}
void SeqListInput(SeqList &L) /*输入若干记录的关键字,存放到顺序表L中*/
{
int i=1; KeyType x;
scanf("%d",&x);
while(x!=-1)
{
L.r[i++].key=x; scanf("%d",&x);
}
L.length=i-1;
}
void SeqListOutput(SeqList L) /*输出顺序表L中各记录的关键字*/
{
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.r[i].key);
printf("\n");
}
int main()
{
SeqList L;
SeqListInput(L);/*输入一组记录的关键字,存放到顺序表L中*/
BubbleSort(L); /*进行冒泡排序*/
SeqListOutput(L);/*输出排序之后的关键字序列*/
return 0;
}
8.6 选择排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*************************************************************
选择排序 头文件
**************************************************************/
#define MAXSIZE 100
typedef int KeyType; /*关键字类型*/
typedef struct
{
KeyType key;
/*InfoType otherinfo;*/
}RedType; /*记录类型*/
typedef struct
{
RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
int length; /*length存放表长*/
}SeqList; /*顺序表类型*/
/*******函数声明*******/
void SeqListInput(SeqList &L); /*输入若干记录的关键字,存放到顺序表L中*/
void SeqListOutput(SeqList L); /*输出顺序表L中各记录的关键字*/
void SelectSort(SeqList &L); /*选择排序*/
/*************************************************************
选择排序 实现文件
**************************************************************/
void SelectSort(SeqList &L)
{
int i, j, minIndex;
for (i = 1; i <= L.length - 1; i++)
{
// 输出前三趟排序后的关键字序列
if (i <= 4 && i>=2)
{
for (j = 1; j <= L.length; j++)
printf("%d ", L.r[j].key);
printf("\n");
}
minIndex = i;
for (j = i + 1; j <= L.length; j++)
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
if (L.r[j].key < L.r[minIndex].key)
minIndex = j;
/********** End **********/
}
// 交换位置
if (minIndex != i)
{
RedType temp = L.r[i];
L.r[i] = L.r[minIndex];
L.r[minIndex] = temp;
}
}
}
void SeqListInput(SeqList &L) /*输入若干记录的关键字,存放到顺序表L中*/
{
int i=1; KeyType x;
scanf("%d",&x);
while(x!=-1)
{
L.r[i++].key=x; scanf("%d",&x);
}
L.length=i-1;
}
void SeqListOutput(SeqList L) /*输出顺序表L中各记录的关键字*/
{
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.r[i].key);
printf("\n");
}
int main()
{
SeqList L;
SeqListInput(L);/*输入一组记录的关键字,存放到顺序表L中*/
SelectSort(L); /*进行选择排序*/
SeqListOutput(L);/*输出排序之后的关键字序列*/
return 0;
}
__EOF__

本文作者:xued
本文链接:https://www.cnblogs.com/xdeyt/p/18140590.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/xdeyt/p/18140590.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?