数据结构实验2
- 5.1 树的三种遍历及叶子
- 5.2 二叉树的层序遍历
- 6.1 图的两种遍历
- 7.1 顺序查找
- 7.2 折半查找
- 7.3 二叉排序树
- 8.1 直插排序
- 8.2 折半插入排序
- 8.3 快速排序
- 8.4 选择排序
- 8.5 堆排序
5.1 树的三种遍历及叶子
//二叉树的先中后序遍历和求叶子结点数目(二叉树的相关操作)
#include "stdafx.h"
#define OK 1
#define NULL 0
#define ERROR 0
#define OVERFLOW -2
#include
#include
#include
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
#include
#include
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
#include //exit()
#include
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;iadjvex=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;iadjvex].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=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=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
#include
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
#include
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
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
#include
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
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
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
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=pivotkey)
--high;
t=L.r[low]; //将比枢轴记录小的记录交换到低端
L.r[low]=L.r[high];
L.r[high]=t;
while(low
8.4 选择排序
//选择排序
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20
#include
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]
8.5 堆排序
//堆排序
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20
#include
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(j0;--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;
}