数据结构期末复习

数据结构

第四章 串

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; 
}

第五章 二叉树

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;
}

第六章 图

6.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;   
}

6.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;   	
}

第七章 查找

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;
}

第八章 排序

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;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值