数据结构实验2

5.1 树的三种遍历及叶子
//二叉树的先中后序遍历和求叶子结点数目(二叉树的相关操作)
#include "stdafx.h"
#define OK 1
#define NULL 0
#define ERROR 0
#define OVERFLOW -2 
#include<process.h>
#include<malloc.h>
#include<stdio.h>
typedef int Status;
typedef char TElemType;
TElemType Nil=' ';
typedef struct BiTNode{
	TElemType data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
Status CreateBiTree(BiTree &T)
{ //根据二叉树的先序序列构造二叉树T 
	TElemType ch;
	scanf("%c",&ch);
    if(ch==Nil||ch=='\n') //T为空
	{
		T=NULL;
		return OK;
	}
	else
    {
		T=(BiTree)malloc(sizeof(BiTNode));
        if(!T)
			exit(OVERFLOW);
		T->data=ch; //生成根结点
     	CreateBiTree(T->lchild); //构造左子树
     	CreateBiTree(T->rchild); //构造右子树
   	}
	return OK;	
}
Status PrintElement(TElemType e)
{ //输出元素e的值 
	printf("%c",e);
	return OK;
}
Status PreOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
{ //先序遍历二叉树T,对每个结点调用函数Visit一次且仅一次 
	if(T) //T不空
   	{
     	Visit(T->data);  //先访问根结点
     	PreOrderTraverse(T->lchild,Visit);  //再先序遍历左子树
     	PreOrderTraverse(T->rchild,Visit);  //最后先序遍历右子树
   	}
   	return OK;
}
Status InOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
{ //中序遍历二叉树T,对每个结点调用函数Visit一次且仅一次
	if(T)
	{
		InOrderTraverse(T->lchild,Visit);  //先中序遍历左子树
    	Visit(T->data);  //再访问根结点
    	InOrderTraverse(T->rchild,Visit);  //最后中序遍历右子树
	}
	return OK;
}
Status PostOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
{ //后序遍历二叉树T,对每个结点调用函数Visit一次且仅一次
	if(T)
	{
		PostOrderTraverse(T->lchild,Visit);  //先后序遍历左子树
		PostOrderTraverse(T->rchild,Visit);  //再后序遍历右子树
		Visit(T->data);  //最后访问根结点
	}
	return OK;
}
Status LeafNumber(BiTree T,int &num)
{ //求二叉树叶子结点数目 
	if(T) //T不空
	{
		if(T->lchild==NULL&&T->rchild==NULL)
		{ //T的左右子树均为空,则T为叶子结点 
			num++;
		}
		LeafNumber(T->lchild,num);  //T非空,求T的左子树的叶子结点数目 
		LeafNumber(T->rchild,num);  //再求T的右子树的叶子结点数目 
	}
	return num;
}
int main()
{
	BiTree t;
	TElemType e;
	int num=0;
	printf("构造二叉树,请按二叉树的先序遍历序列输入:\n");
	CreateBiTree(t);
	printf("该二叉树的先序遍历序列为:"); 
	PreOrderTraverse(t,PrintElement);
	printf("\n");
	printf("该二叉树的中序遍历序列为:");
	InOrderTraverse(t,PrintElement);
	printf("\n");
	printf("该二叉树的后序遍历序列为:"); 
	PostOrderTraverse(t,PrintElement);
	printf("\n");
	printf("该二叉树中叶子结点的数目为:%d\n",LeafNumber(t,num));
	return 0;
}
5.2 二叉树的层序遍历
//二叉树的层序遍历(二叉树和队列的相关操作)
#define OK 1
#define NULL 0
#define TRUE 1
#define FALSE 0 
#define ERROR 0
#define OVERFLOW -2 
#include<process.h>
#include<malloc.h>
#include<stdio.h>
typedef int Status;
typedef char TElemType;
TElemType Nil=' ';
typedef struct BiTNode{
	TElemType data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef BiTree QElemType;
typedef struct QNode
{
	QElemType data;
   	QNode *next;
}*QueuePtr;
struct LinkQueue
{
	QueuePtr front,rear; //队头、队尾指针
};
Status InitQueue(LinkQueue &Q)
{ //构造一个空队列Q
	if(!(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode))))
		exit(OVERFLOW);
   	Q.front->next=NULL;
   	return OK;
}
Status DestroyQueue(LinkQueue &Q)
{ //销毁队列Q(无论空否均可)
	while(Q.front)
	{
		Q.rear=Q.front->next;
     	free(Q.front);
     	Q.front=Q.rear;
   	}
   	return OK;
}
Status QueueEmpty(LinkQueue Q)
{ //若Q为空队列,则返回TRUE,否则返回FALSE
	if(Q.front==Q.rear)
     	return TRUE;
	else
		return FALSE;
}
Status EnQueue(LinkQueue &Q,QElemType e)
{ //插入元素e为Q的新的队尾元素
	QueuePtr p;
	if(!(p=(QueuePtr)malloc(sizeof(QNode)))) //存储分配失败
		exit(OVERFLOW);
	p->data=e;
	p->next=NULL;
	Q.rear->next=p;
	Q.rear=p;
	return OK;
}
Status DeQueue(LinkQueue &Q,QElemType &e)
{ //若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR
	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;
   	free(p);
   	return OK;
}
Status CreateBiTree(BiTree &T)
{
	TElemType ch;
	scanf("%c",&ch);
    if(ch==Nil||ch=='\n') //空
	{
		T=NULL;
		return OK;
	}
	else
    {
		T=(BiTree)malloc(sizeof(BiTNode));
        if(!T)
			exit(OVERFLOW);
		T->data=ch;  //生成根结点
     	CreateBiTree(T->lchild);  //构造左子树
     	CreateBiTree(T->rchild);  //构造右子树
   	}
	return OK;	
}
Status PrintElement(TElemType e)
{ //输出元素e 
	printf("%c",e);
	return OK;
}
Status LevelOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
{ //层序遍历二叉树T,对每个结点调用函数Visit一次且仅一次 
	LinkQueue q;
   	QElemType a;
   	if(T)
   	{
		InitQueue(q);
     	EnQueue(q,T); //将根结点T入队 
     	while(!QueueEmpty(q))
     	{
       		DeQueue(q,a); //队首元素出队 
       		Visit(a->data); //访问出队元素 
       		if(a->lchild!=NULL) //若该元素左子树不为空, 将其左子树入队 
         		EnQueue(q,a->lchild);
       		if(a->rchild!=NULL) //若该元素右子树不为空, 将其右子树入队 
         		EnQueue(q,a->rchild);
     	}
     	printf("\n");
   	}
   	DestroyQueue(q); //销毁队列 
   	return OK;
}
int main()
{
	BiTree t;
	LinkQueue q;
	InitQueue(q);
	printf("构造二叉树,请按二叉树的先序遍历序列输入:\n");
	CreateBiTree(t);
	printf("该二叉树的层序遍历序列为:"); 
	LevelOrderTraverse(t,PrintElement);	
	return 0;
}

6.1 图的两种遍历
//图的深度优先遍历和广度优先遍历(利用图的邻接表表示实现) 
//#include "stdafx.h"
#define MAX_VERTEX_NUM 20
#define OK 1 
#define ERROR 0
#define TRUE 1
#define FALSE 0
#include<stdio.h>
#include<process.h> //exit()
#include<malloc.h>
typedef int Boolean;
typedef int Status;
typedef int VertexType;
//图的邻接表存储表示 
typedef struct ArcNode{
	int adjvex;  //该弧所指向的顶点的位置 
	struct ArcNode *nextarc; //指向下一条弧的指针 
}ArcNode;
typedef struct VNode{
	VertexType data;  //顶点信息 
	ArcNode *firstarc;  //指向第一条依附该结点的弧的指针 
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct {
	AdjList vertices;
	int vexnum,arcnum; //图的当前顶点数和弧数 
	int kind;  //图的种类标志,图的种类为邻接表 
}ALGraph;
int LocateVex(ALGraph G,VertexType u)
{ //操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1
	int i;
	for(i=0;i<G.vexnum;++i)
	{
		if(u==G.vertices[i].data)
			return i;
	}
	return -1;
}
Status CreateGraph(ALGraph &G)
{ //创建图G 
	int i,j,k;
	VertexType va,vb;
	ArcNode *p;
	printf("请输入图的顶点数,边数:");
	scanf("%d,%d",&G.vexnum,&G.arcnum);
	printf("请输入%d个顶点的值:\n",G.vexnum);
	for(i=0;i<G.vexnum;++i)
	{
		scanf("%d",&G.vertices[i].data);
		G.vertices[i].firstarc=NULL;
	}
	printf("请按顺序输入每条边的弧头和弧尾:\n");
	for(k=0;k<G.arcnum;k++)
	{
		scanf("%d,%d",&va,&vb);
		i=LocateVex(G,va);
		j=LocateVex(G,vb);
		p=(ArcNode*)malloc(sizeof(ArcNode));
		p->adjvex=j;
		p->nextarc=G.vertices[i].firstarc;  //插在表头,使用头插法 
     	G.vertices[i].firstarc=p;
     	p=(ArcNode*)malloc(sizeof(ArcNode));
       	p->adjvex=i;
       	p->nextarc=G.vertices[j].firstarc;  //插在表头,使用头插法 
       	G.vertices[j].firstarc=p;
	}
	return OK;
}
void Display(ALGraph G)
{ //输出图G中顶点和边的关系 
	int i;
    ArcNode *p;
    printf("\n输出该图:\n");
    printf("共%d个顶点:\n",G.vexnum);
	for(i=0;i<G.vexnum;++i)
	printf("V%d ",G.vertices[i].data);
    printf("\n%d条边:\n",G.arcnum);
    for(i=0;i<G.vexnum;i++)
	{
		p=G.vertices[i].firstarc;
       	while(p)
     	{
       		if(i<G.vertices[p->adjvex].data)
    		{
           		printf("V%d-V%d ",G.vertices[i].data,G.vertices[p->adjvex].data);
           		printf("\n");
        	}
       		p=p->nextarc;
     	}
   	}
}
int GetVex(ALGraph G,int v)
{ //初始条件:图G存在,v是G中某个顶点的序号。操作结果: 返回v的值
	if(v>=G.vexnum||v<0)
     	exit(ERROR);
   	return G.vertices[v].data;
}
void visit(int v)
{ //输出顶点v
	printf("V%d ",v);
}
int FirstAdjVex(ALGraph G,VertexType v)
{ //返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1
	ArcNode *p;
   	int v1;
   	v1=LocateVex(G,v); //v1为顶点v在图G中的序号
   	p=G.vertices[v1].firstarc;
   	if(p)
     	return p->adjvex;
   	else
     	return -1;
}
int NextAdjVex(ALGraph G,VertexType v,VertexType w)
{ //返回v的(相对于w的)下一个邻接顶点的序号
  //若w是v的最后一个邻接点,则返回-1
	ArcNode *p;
   	int v1,w1;
   	v1=LocateVex(G,v); //v1为顶点v在图G中的序号
   	w1=LocateVex(G,w); //w1为顶点w在图G中的序号
   	p=G.vertices[v1].firstarc;
   	while(p&&p->adjvex!=w1) //指针p不空且所指表结点不是w
		p=p->nextarc;
   	if(!p||!p->nextarc) //没找到w或w是最后一个邻接点
		return -1;
	else 
		return p->nextarc->adjvex; //返回v的(相对于w的)下一个邻接顶点的序号
}
Boolean visited[MAX_VERTEX_NUM]; //访问标志数组(全局量)
void(*VisitFunc)(int v); //函数变量(全局量)
void DFS(ALGraph G,int v)
{ //从第v个顶点出发递归地深度优先遍历图G
	int w;
   	VertexType v1,w1;
   	v1=GetVex(G,v);
   	visited[v]=TRUE; //设置访问标志为TRUE(已访问)
   	VisitFunc(G.vertices[v].data); //访问第v个顶点
   	for(w=FirstAdjVex(G,v1);w>=0;w=NextAdjVex(G,v1,GetVex(G,w)))
		if(!visited[w])
			DFS(G,w); //对v的尚未访问的邻接点w递归调用DFS
 }
void DFSTraverse(ALGraph G,void(*Visit)(int))
{ //对图G作深度优先遍历
	int v;
   	VisitFunc=Visit; //使用全局变量VisitFunc,使DFS不必设函数指针参数
   	for(v=0;v<G.vexnum;v++)
		visited[v]=FALSE; //访问标志数组初始化
	for(v=0;v<G.vexnum;v++)
		if(!visited[v])
			DFS(G,v); //对尚未访问的顶点调用DFS
	printf("\n");
}
typedef int QElemType; //队列类型
#define MAXQSIZE 5 //最大队列长度
#define OVERFLOW 3
struct SqQueue
{
	QElemType *base; 
	int front; //头指针
	int rear; //尾指针
};
Status InitQueue(SqQueue &Q)
{ //构造一个空队列Q 
	Q.base=(QElemType *)malloc(MAXQSIZE*sizeof(QElemType));
	if(!Q.base) exit(OVERFLOW);
	Q.front=Q.rear=0;
	return OK;
}
Status EnQueue(SqQueue &Q,QElemType e)
{ //插入元素e为Q的新的队尾元素 
	if(Q.rear>=MAXQSIZE)
	{
		Q.base=(QElemType *)realloc(Q.base,(Q.rear+1)*sizeof(QElemType));
		if(!Q.base) return ERROR;
	}
	*(Q.base+Q.rear)=e;
	Q.rear++;
	return OK;
}
Status QueueEmpty(SqQueue Q)
{ //若队列空,返回TRUE,否则返回FALSE 
	if(Q.front==Q.rear)
		return TRUE;
	else
		return FALSE;
}
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;
	return OK;
}
void BFSTraverse(ALGraph G,void(*Visit)(int))
{ //按广度优先非递归遍历图G。使用辅助队列Q和访问标志数组visited
	int v,u,w;
   	VertexType u1,w1;
   	SqQueue Q;
   	for(v=0;v<G.vexnum;++v)
		visited[v]=FALSE;  //置初值
   	InitQueue(Q);  //置空的辅助队列Q
   	for(v=0;v<G.vexnum;v++) 
		if(!visited[v]) //v尚未访问
		{
			visited[v]=TRUE;  //对访问过的做标记 
	       	Visit(G.vertices[v].data);
	       	EnQueue(Q,v);  //v入队列
	       	while(!QueueEmpty(Q))  //队列不空
	       	{
				DeQueue(Q,u); //队头元素出队并置为u
	         	u1=GetVex(G,u);
	         	for(w=FirstAdjVex(G,u1);w>=0;w=NextAdjVex(G,u1,GetVex(G,w)))
	           		if(!visited[w]) //w为u的尚未访问的邻接顶点
	           		{
	             		visited[w]=TRUE;
	             		Visit(G.vertices[w].data);
	             		EnQueue(Q,w); //w入队
	           		}
	       	}
	    }
	printf("\n");
}
int main()
{
	ALGraph g;
    CreateGraph(g);
   	Display(g);
   	printf("\n深度优先搜索的结果:\n");
   	DFSTraverse(g,visit);
   	printf("\n广度优先搜索的结果:\n");
   	BFSTraverse(g,visit);
	return 0;
}

7.1 顺序查找
//顺序查找 
#define ERROR 0
#define OK 1
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#include<stdlib.h>
#include<stdio.h>
typedef int ElemType;
typedef int Status;
typedef int KeyType;
typedef struct {
	ElemType *elem;
	int length;
}SSTable; 
int r[1000];  //定义全局数组r
Status Create_Seq(SSTable &ST,int n)
{ //创建元素个数为n的顺序表ST 
	int i;
	ST.elem=(ElemType*)calloc(n+1,sizeof(ElemType));
	if(!ST.elem)
		return ERROR;
	for(i=1;i<=n;i++)
	{
		ST.elem[i]=r[i-1];
	}
	ST.length=n;
	return OK;
}
int Search_Seq(SSTable ST,KeyType key)
{ //在顺序表ST中顺序查找其关键字等于key的数据元素 
	int i;
    *(ST.elem)=key; //哨兵
    for(i=ST.length;!EQ(*(ST.elem+i),key);--i); //从后往前找
    return i; //找不到时,i为0,即与哨兵相等 
}
int main()
{
	int n;
	printf("请输入元素总个数:");
	scanf("%d",&n);
	printf("请输入这%d个元素(以/结束):\n",n);
	for(int i=1;i<=n;++i)
	{
		scanf("%d ",&r[i-1]); //将元素依次存入全局数组r中 
		if(r[i-1]=='/')
			break;
	}
	SSTable st;
	Create_Seq(st,n);
	KeyType key;
	printf("请输入要查找的元素:");
	fflush(stdin);
	scanf("%d",&key); 
	int t;
	t=Search_Seq(st,key);
	if(t==0) printf("经顺序查找,该表中不存在元素%d\n",key);
	else printf("经顺序查找,元素%d的位置为:%d\n",key,t);
	return 0;
}

7.2 折半查找
//折半查找(需先排序) 
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OK 1
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#include<stdlib.h>
#include<stdio.h>
typedef int ElemType;
typedef int Status;
typedef int KeyType;
typedef struct {
	ElemType *elem;
	int length;
}SSTable; 
int r[1000]; //定义全局数组r 
Status Create_Seq(SSTable &ST,int n)
{ //创建一个含n个数据元素的静态查找表ST
	int i;
	ST.elem=(ElemType*)calloc(n+1,sizeof(ElemType));
	if(!ST.elem)
		return ERROR;
	for(i=1;i<=n;i++)
	{
		ST.elem[i]=r[i-1];
	}
	ST.length=n;
	return OK;
}
void Ascend(SSTable &ST)
{ //重建静态查找表为按关键字非降序排序
	int i,j,k;
    for(i=1;i<ST.length;i++)   //利用简单选择排序方法进行排序
    {
		k=i;
        ST.elem[0]=ST.elem[i]; //待比较值存入ST.elem[0]单元
      	for(j=i+1;j<=ST.length;j++)  
      	{   
			if(LT(ST.elem[j],ST.elem[0]))
	       	{
				k=j;
	         	ST.elem[0]=ST.elem[j];
	       	}
		} 
     	if(k!=i) //与当前关键字最小的记录进行交换 
     	{
			ST.elem[k]=ST.elem[i];
       		ST.elem[i]=ST.elem[0];
     	}
   	}
}
Status IsAscending(SSTable ST,int n)
{ //若静态查找表ST按关键字非降序排列,返回TRUE,否则返回FALSE 
	int t=0;
	for(int i=2;i<=n;i++)
	{
		if(ST.elem[i]<ST.elem[i-1])
			t++;
	}
	if(!t)	return TRUE;
	else return FALSE;
}
Status Create_Ord(SSTable &ST,int n)
{ //构造一个含n个数据元素的静态按关键字非降序查找表ST
  //数据来自全局数组r
   	Create_Seq(ST,n);
   	if(!IsAscending(ST,n))
		Ascend(ST);
   	return OK;
}
int Search_Bin(SSTable ST,KeyType key)
{ //在有序表ST中折半查找其关键字等于key的数据元素。若找到,则函数值为
  //该元素在表中的位置,否则为0
	int low,high,mid;
	low=1;  //置区间初值
	high=ST.length;
   	while(low<=high)
   	{
		mid=(low+high)/2;
     	if EQ(key,ST.elem[mid])  //找到待查元素
			return mid;
     	else if LT(key,ST.elem[mid])
			high=mid-1; //继续在前半区间进行查找
     	else
			low=mid+1; //继续在后半区间进行查找
   	}
   	return 0; //顺序表中不存在待查元素
}
Status Traverse(SSTable ST,void(*Visit)(ElemType))
{ //按顺序对ST的每个元素调用函数Visit()一次且仅一次。
  //一旦Visit()失败,则操作失败
	ElemType *p;
   	int i; 
   	p=++ST.elem; //p指向第一个元素
   	for(i=1;i<=ST.length;i++)
		Visit(*p++);
	printf("\n");
   	return OK;
}
void print(ElemType c) //Traverse()调用的函数
{ //输出元素c 
	printf("%d ",c);
}
int main()
{
	int n;
	printf("请输入元素总个数:");
	scanf("%d",&n);
	printf("请输入这%d个元素(以/结束):\n",n);
	for(int i=1;i<=n;++i)
	{
		scanf("%d ",&r[i-1]);
		if(r[i-1]=='/')
			break;
	}
	SSTable st;
	Create_Ord(st,n);
	fflush(stdin);
	printf("\n经排序后,该表为:\n");
	Traverse(st,print);
	int key;
	printf("\n请输入要查找的元素:");
	fflush(stdin);
	scanf("%d",&key);
	int t;
	t=Search_Bin(st,key);
	if(t==0) printf("\n经折半查找,该顺序表中不存在元素%d\n",key);
	else printf("\n经折半查找,表中存在该元素,且元素%d在顺序表中的位置为:%d\n",key,t);
	return 0;
}


7.3 二叉排序树
//二叉排序树的查找、插入、删除算法 
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define OK 1
#define NULL 0 
#define FALSE 0
#define TRUE 1 
#include<stdio.h>
#include<stdlib.h> 
typedef int Status;
typedef int ElemType;
typedef ElemType TElemType;
typedef struct BSTNode{
	ElemType data;
	int bf;
	BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
typedef struct BiTNode{
	TElemType data;
	BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
Status InitDSTable(BiTree &DT)
{ //初始化二叉排序树DT 
	DT=NULL;
	return OK;
}
void DestroyDSTable(BiTree &DT)
{ //销毁二叉排序树DT 
	if(DT) //DT不为空 
	{
		if(DT->lchild)
			DestroyDSTable(DT->lchild);
		if(DT->rchild)
			DestroyDSTable(DT->rchild);
		free(DT);
		DT=NULL;
	}
}
BiTree SearchBST(BiTree T,int key)
{ //在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素,
  //若查找成功,则返回指向该数据元素结点的指针,否则返回空指针。
	if((!T)||EQ(key,T->data))
		return T; //查找结束
   	else if(LT(key,T->data)) 
     	return SearchBST(T->lchild,key); //在左子树中继续查找
   	else
     	return SearchBST(T->rchild,key); //在右子树中继续查找
}
Status SearchBST(BiTree &T,int key,BiTree f,BiTree &p) 
{ //在根指针T所指二叉排序树中递归地查找其关键字等于key的数据元素,若查找
  //成功,则指针p指向该数据元素结点,并返回TRUE,否则指针p指向查找路径上
  //访问的最后一个结点并返回FALSE,指针f指向T的双亲,其初始调用值为NULL
	if(!T)  //查找不成功
   	{
		p=f;
     	return FALSE;
   	}
	else if(EQ(key,T->data))  //查找成功
   	{
		p=T;
     	return TRUE;
   	}
   	else if(LT(key,T->data)) 
		SearchBST(T->lchild,key,T,p);  //在左子树中继续查找
   	else	SearchBST(T->rchild,key,T,p);  //在右子树中继续查找
}
Status InsertBST(BiTree &T, ElemType e)
{ //当二叉排序树T中不存在关键字等于e.key的数据元素时,插入e并返回TRUE
   //否则返回FALSE
	BiTree p,s;
   	Status flag;
   	if(!SearchBST(T,e,NULL,p)) //查找不成功
   	{
		s=(BiTree)malloc(sizeof(BiTNode));
     	s->data=e;
     	s->lchild=s->rchild=NULL;
     	if(!p)   //T为空 
			T=s;  //被插结点*s为新的根结点
     	else if(LT(e,p->data))
			p->lchild=s;  //被插结点*s为左孩子
		else	p->rchild=s;  //被插结点*s为右孩子
		return TRUE;
   	}
   	else	
	   return FALSE;  //树中已有关键字相同的结点,不再插入
}
void Delete(BiTree &p)
{ //从二叉排序树中删除结点p,并重接它的左或右子树
	BiTree q,s;
   	if(!p->rchild) //右子树空则只需重接它的左子树
   	{
		q=p;
     	p=p->lchild;
     	free(q);
   	}
   	else if(!p->lchild) //只需重接它的右子树
   	{
		q=p;
     	p=p->rchild;
     	free(q);
   	}
   	else //左右子树均不空
   	{
		q=p;
     	s=p->lchild;
     	while(s->rchild) //转左,然后向右到尽头
     	{
			q=s;
       		s=s->rchild;
     	}
     	p->data=s->data; //s指向被删结点的"前驱"
     	if(q!=p)
       		q->rchild=s->lchild; //重接*q的右子树
     	else
       		q->lchild=s->lchild; //重接*q的左子树
     	free(s);
   	}
}
Status DeleteBST(BiTree &T,int key)
{ //若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点
   //并返回TRUE;否则返回FALSE
	if(!T) //不存在关键字等于key的数据元素
    	return FALSE;
   	else
   	{
    	if(EQ(key,T->data)) // 找到关键字等于key的数据元素
       		Delete(T);
     	else if(LT(key,T->data))
       		DeleteBST(T->lchild,key);
     	else	DeleteBST(T->rchild,key);
     	return TRUE;
   	}
}
void print(ElemType c)
{ //输出元素c 
	printf("%d ",c);
}
void TraverseDSTable(BiTree DT,void(*Visit)(ElemType))
{ //按关键字的顺序对DT的每个结点调用函数Visit()一次且至多一次
	if(DT)
	{
		TraverseDSTable(DT->lchild,Visit); //先中序遍历左子树
     	Visit(DT->data); //再访问根结点
     	TraverseDSTable(DT->rchild,Visit); //最后中序遍历右子树
   	}
}
int main()
{
	BiTree dt,p,f;
	int key,n,a,b,c,d;
	InitDSTable(dt);
	printf("请输入元素个数:");
	scanf("%d",&n);
	printf("请输入序列(以空格间隔、“/”结束):\n");
	for(int i=1;i<=n;i++)
	{
		scanf("%d ",&a);
		if(a=='/')
			break;
		InsertBST(dt,a);
	}
	printf("输出该二叉排序树为:\n");
	TraverseDSTable(dt,print);
	printf("\n\n请输入要查找的值: ");
	fflush(stdin);
	scanf("%d",&b);
   	p=SearchBST(dt,b);
   	if(p)
		printf("表中存在此元素\n");
   	else
		printf("表中不存在此元素\n");
	printf("\n请输入要插入的值: ");
	scanf("%d",&c);
	InsertBST(dt,c);
	printf("插入此值后,该二叉排序树为:\n");
    TraverseDSTable(dt,print);
	printf("\n\n请输入要删除的值: ");
	scanf("%d",&d);
	DeleteBST(dt,d);
    printf("删除此值后,该二叉排序树为:\n");
    TraverseDSTable(dt,print);
	DestroyDSTable(dt);  //销毁二叉排序树dt
	return 0;
}


8.1 直插排序
//直接插入排序 
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20
#include<stdio.h> 
typedef int ElemType;
struct SqList //顺序表类型
{
	ElemType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元
	int length; //顺序表长度
};

void InsertSort(SqList &L)
{ //对顺序表L作直接插入排序
	int i,j;
	for(i=2;i<=L.length;++i)
	if (LT(L.r[i],L.r[i-1])) //"<",需将L.r[i]插入有序子表
     {
       L.r[0]=L.r[i];  //复制为哨兵
       for(j=i-1;LT(L.r[0],L.r[j]);--j)
         L.r[j+1]=L.r[j];  //记录后移
       L.r[j+1]=L.r[0];  //插入到正确位置
     }
}
void print(SqList L)
{ //输出表L 
	int i;
	for(i=1;i<=L.length;i++)
		printf("%d ",L.r[i]);
	printf("\n");
}
int main()
{
	int n,a;
	SqList l;
	printf("请输入要排序的序列的长度:");
	scanf("%d",&n);
	l.length=n;
	printf("请输入该序列(以空格间隔、“/”结束):\n");
	for(int i=1;i<=n;i++)
	{
		scanf("%d ",&a);
		if(a=='/')
			break;
		l.r[i]=a;
	}
	InsertSort(l);
	printf("\n经直接插入排序,序列变为:\n");
	print(l);
	return 0;
}

8.2 折半插入排序
//折半插入排序 
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20
#include<stdio.h> 
typedef int ElemType;
struct SqList //顺序表类型
{
	ElemType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元
	int length; //顺序表长度
};

void BInsertSort(SqList &L)
{ //对顺序表L作折半插入排序
	int i,j,m,low,high;
   	for(i=2;i<=L.length;++i)
   	{
		L.r[0]=L.r[i]; //将L.r[i]暂存到L.r[0]
     	low=1;
     	high=i-1;
		while(low<=high)
     	{  //在r[low..high]中折半查找有序插入的位置
			m=(low+high)/2;  //折半
       		if LT(L.r[0],L.r[m])
         		high=m-1;  //插入点在低半区
       		else
         		low=m+1;  //插入点在高半区
		}
     	for(j=i-1;j>=high+1;--j)
       	L.r[j+1]=L.r[j];  //记录后移
     	L.r[high+1]=L.r[0];  //插入
   	}
}
void print(SqList L)
{ //输出表L 
	int i;
	for(i=1;i<=L.length;i++)
		printf("%d ",L.r[i]);
	printf("\n");
}
int main()
{
	int n,a;
	SqList l;
	printf("请输入要排序的序列的长度:");
	scanf("%d",&n);
	l.length=n;
	printf("请输入该序列(以空格间隔、“/”结束):\n");
	for(int i=1;i<=n;i++)
	{
		scanf("%d ",&a);
		if(a=='/')
			break;
		l.r[i]=a;
	}
	BInsertSort(l);
	printf("\n经折半插入排序,序列变为:\n");
	print(l);
	return 0;
}

8.3 快速排序
//快速排序 
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20
#include<stdio.h> 
typedef int ElemType;
struct SqList //顺序表类型
{
	ElemType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元
	int length; //顺序表长度
};
int Partition(SqList &L,int low,int high)
{ //交换顺序表L中子表L.r[low..high]的记录,使枢轴记录到位,
   //并返回其所在位置,此时在它之前(后)的记录均不大(小)于它
	int t;
	int pivotkey;
	pivotkey=L.r[low]; //用子表的第一个记录作枢轴记录
   	while(low<high)
   	{ //从表的两端交替地向中间扫描
		while(low<high&&L.r[high]>=pivotkey)
       		--high;
     	t=L.r[low];  //将比枢轴记录小的记录交换到低端
     	L.r[low]=L.r[high];
     	L.r[high]=t;
     	while(low<high&&L.r[low]<=pivotkey)
       	++low;
     	t=L.r[low]; //将比枢轴记录大的记录交换到高端
     	L.r[low]=L.r[high];
     	L.r[high]=t;
   	}
   	return low; //返回枢轴所在位置
}
void QSort(SqList &L,int low,int high)
{ //对顺序表L中的子序列L.r[low..high]作快速排序
	int pivotloc;
   	if(low<high)
   	{ //长度大于1
	     pivotloc=Partition(L,low,high); //将L.r[low..high]一分为二
	     QSort(L,low,pivotloc-1); //对低子表递归排序,pivotloc是枢轴位置
	     QSort(L,pivotloc+1,high); //对高子表递归排序
	}
}
void QuickSort(SqList &L)
{ //对顺序表L作快速排序
	QSort(L,1,L.length);
}
void print(SqList L)
{ //输出表L 
	int i;
	for(i=1;i<=L.length;i++)
		printf("%d ",L.r[i]);
	printf("\n");
}
int main()
{
	int n,a;
	SqList l;
	printf("请输入要排序的序列的长度:");
	scanf("%d",&n);
	l.length=n;
	printf("请输入该序列(以空格间隔、“/”结束):\n");
	for(int i=1;i<=n;i++)
	{
		scanf("%d ",&a);
		if(a=='/')
			break;
		l.r[i]=a;
	}
	QuickSort(l);
	printf("\n经快速排序,序列变为:\n");
	print(l);
	return 0;
}

8.4 选择排序
//选择排序 
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20
#include<stdio.h> 
typedef int ElemType;
struct SqList //顺序表类型
{
	ElemType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元
	int length; //顺序表长度
};
int SelectMinKey(SqList L,int i)
{ //返回在L.r[i..L.length]中key最小的记录的序号
	int min;
   	int j,k;
   	k=i; 
   	min=L.r[i];
   	for(j=i+1;j<=L.length;j++) 
	{ //将后面的记录依次与min(L.r[i])比较 
		if(L.r[j]<min) 
     	{
			k=j;
       		min=L.r[j];
     	}
	} 
		
   	return k;
}
void SelectSort(SqList &L)
{ //对顺序表L作简单选择排序
	int i,j;
   	int t;
   	for(i=1;i<L.length;++i)
   	{ //选择第i小的记录,并交换到位
		j=SelectMinKey(L,i); //在L.r[i..L.length]中选择key最小的记录
     	if(i!=j)
     	{ //与第i个记录交换
			t=L.r[i];
       		L.r[i]=L.r[j];
       		L.r[j]=t;
     	}
   	}
}
void print(SqList L)
{ //输出表L 
	int i;
	for(i=1;i<=L.length;i++)
		printf("%d ",L.r[i]);
	printf("\n");
}
int main()
{
	int n,a;
	SqList l;
	printf("请输入要排序的序列的长度:");
	scanf("%d",&n);
	l.length=n;
	printf("请输入该序列(以空格间隔、“/”结束):\n");
	for(int i=1;i<=n;i++)
	{
		scanf("%d ",&a);
		if(a=='/')
			break;
		l.r[i]=a;
	}
	SelectSort(l);
	printf("\n经选择排序,序列变为:\n");
	print(l);
	return 0;
}

8.5 堆排序
//堆排序 
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20
#include<stdio.h> 
typedef int ElemType;
struct SqList 
{
	ElemType r[MAXSIZE+1];
	int length; 
};
typedef SqList HeapType; //堆采用顺序表存储表示
void HeapAdjust(HeapType &H,int s,int m) 
{ //调整H.r[s]的关键字,使H.r[s..m]成为一个大顶堆 
	int rc;
   	int j;
   	rc=H.r[s];
   	for(j=2*s;j<=m;j*=2)
   	{ //沿key较大的孩子结点向下筛选
		if(j<m&&LT(H.r[j],H.r[j+1]))
       		++j; //j为key较大的记录的下标
     	if(!LT(rc,H.r[j]))
       		break; //rc应插入在位置s上
     	H.r[s]=H.r[j];
     	s=j;
   	}
   	H.r[s]=rc; //插入
}
void HeapSort(HeapType &H)
{ //对顺序表H进行堆排序
	int t;
   	int i;
   	for(i=H.length/2;i>0;--i) // 把H.r[1..H.length]建成大顶堆
     	HeapAdjust(H,i,H.length);
   	for(i=H.length;i>1;--i)
   	{ // 将堆顶记录和当前未经排序子序列H.r[1..i]中最后一个记录相互交换
     	t=H.r[1];
     	H.r[1]=H.r[i];
     	H.r[i]=t;
     	HeapAdjust(H,1,i-1); // 将H.r[1..i-1]重新调整为大顶堆
   	}
}
void print(HeapType H)
{ //输出堆H 
	int i;
   	for(i=1;i<=H.length;i++)
     	printf("%d ",H.r[i]);
   	printf("\n");
}
int main()
{
	int n,a;
	HeapType h;
	printf("请输入要排序的序列的长度:");
	scanf("%d",&n);
	h.length=n;
	printf("请输入该序列(以空格间隔、“/”结束):\n");
	for(int i=1;i<=n;i++)
	{
		scanf("%d ",&a);
		if(a=='/')
			break;
		h.r[i]=a;
	}
	HeapSort(h);
	printf("\n经堆排序,序列变为:\n");
	print(h);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值