c语言大顶堆函数 大顶堆数组

c语言:已知数组a中的元素(a[1]..a[n])

既然其它数都已经排好,只需要排最上面一个数了,算法比较简单,一看就应该能明白.我设计的是从A[0]....A[N-1],如果你要从A[1]...A[N]的话,把那个2*I+1,2*I+2改成2*I,2*I+1即可...

创新互联长期为超过千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为托克托企业提供专业的网站设计、成都网站设计,托克托网站改版等技术服务。拥有十多年丰富建站经验和众多成功案例,为您定制开发。

#include stdio.h

void swap(int *x, int *y){

int temp = *x;

*x = *y;

*y = temp;

}

void sift(int a[],int n){ //调整堆顶元素

int i = 0;

while(2*i+2 n){ //找出最大的与a[i]交换,如果就是本身退出循环

int max = i;

if(a[max] a[2*i+1]){

max = 2*i+1;

}

if(a[max] a[2*i+2]){

max = 2*i+2;

}

if(max == i){

break;

}

else{

swap(a[i], a[max]);

i = max;

}

}

}

int main(){

int a[8] = {10, 88, 40, 50, 76, 9, 32, 5}, i;

sift(a, 8);

for(i=0; i8; i++){

printf("%d\t", a[i]);

}

printf("\n");

return 0;

}

C语言:1,2,3,4,5是否能构成大根堆,为什么?

能构成大根堆,因为大根堆要求根节点大于左右节点,且5放在根节点,接下来以3.4为左右孩子,然后将1.2作为3或4的孩子即可,

最大堆是堆的两种形式之一。

根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆,又称最大堆(大顶堆)。

大根堆要求根节点的关键字既大于或等于左子树的关键字值,又大于或等于右子树的关键字值。

用c 语言编写,对数组A中的N(0

//总共给你整理了7种排序算法:希尔排序,链式基数排序,归并排序

//起泡排序,简单选择排序,树形选择排序,堆排序,先自己看看吧,

//看不懂可以再问身边的人或者查资料,既然可以上网,我相信你所在的地方信息流通方式应该还行,所有的程序全部在VC++6.0下编译通过

//希尔排序

#includestdio.h

typedef int InfoType; // 定义其它数据项的类型

#define EQ(a,b) ((a)==(b))

#define LT(a,b) ((a)(b))

#define LQ(a,b) ((a)=(b))

#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度

typedef int KeyType; // 定义关键字类型为整型

struct RedType // 记录类型

{

KeyType key; // 关键字项

InfoType otherinfo; // 其它数据项,具体类型在主程中定义

};

struct SqList // 顺序表类型

{

RedType r[MAXSIZE+1]; // r[0]闲置或用作哨兵单元

int length; // 顺序表长度

};

void ShellInsert(SqList L,int dk)

{ // 对顺序表L作一趟希尔插入排序。本算法是和一趟直接插入排序相比,

// 作了以下修改:

// 1.前后记录位置的增量是dk,而不是1;

// 2.r[0]只是暂存单元,不是哨兵。当j=0时,插入位置已找到。算法10.4

int i,j;

for(i=dk+1;i=L.length;++i)

if LT(L.r[i].key,L.r[i-dk].key)

{ // 需将L.r[i]插入有序增量子表

L.r[0]=L.r[i]; // 暂存在L.r[0]

for(j=i-dk;j0LT(L.r[0].key,L.r[j].key);j-=dk)

L.r[j+dk]=L.r[j]; // 记录后移,查找插入位置

L.r[j+dk]=L.r[0]; // 插入

}

}

void print(SqList L)

{

int i;

for(i=1;i=L.length;i++)

printf("%d ",L.r[i].key);

printf("\n");

}

void print1(SqList L)

{

int i;

for(i=1;i=L.length;i++)

printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);

printf("\n");

}

void ShellSort(SqList L,int dlta[],int t)

{ // 按增量序列dlta[0..t-1]对顺序表L作希尔排序。算法10.5

int k;

for(k=0;kt;++k)

{

ShellInsert(L,dlta[k]); // 一趟增量为dlta[k]的插入排序

printf("第%d趟排序结果: ",k+1);

print(L);

}

}

#define N 10

#define T 3

void main()

{

RedType d[N]=,,,,,,,,,};

SqList l;

int dt[T]=; // 增量序列数组

for(int i=0;iN;i++)

l.r[i+1]=d[i];

l.length=N;

printf("排序前: ");

print(l);

ShellSort(l,dt,T);

printf("排序后: ");

print1(l);

}

/*****************************************************************/

//链式基数排序

typedef int InfoType; // 定义其它数据项的类型

typedef int KeyType; // 定义RedType类型的关键字为整型

struct RedType // 记录类型(同c10-1.h)

{

KeyType key; // 关键字项

InfoType otherinfo; // 其它数据项

};

typedef char KeysType; // 定义关键字类型为字符型

#includestring.h

#includectype.h

#includemalloc.h // malloc()等

#includelimits.h // INT_MAX等

#includestdio.h // EOF(=^Z或F6),NULL

#includestdlib.h // atoi()

#includeio.h // eof()

#includemath.h // floor(),ceil(),abs()

#includeprocess.h // exit()

#includeiostream.h // cout,cin

// 函数结果状态代码

#define TRUE 1

#define FALSE 0

#define OK 1

#define ERROR 0

#define INFEASIBLE -1

typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等

typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE

#define MAX_NUM_OF_KEY 8 // 关键字项数的最大值

#define RADIX 10 // 关键字基数,此时是十进制整数的基数

#define MAX_SPACE 1000

struct SLCell // 静态链表的结点类型

{

KeysType keys[MAX_NUM_OF_KEY]; // 关键字

InfoType otheritems; // 其它数据项

int next;

};

struct SLList // 静态链表类型

{

SLCell r[MAX_SPACE]; // 静态链表的可利用空间,r[0]为头结点

int keynum; // 记录的当前关键字个数

int recnum; // 静态链表的当前长度

};

typedef int ArrType[RADIX];

void InitList(SLList L,RedType D[],int n)

{ // 初始化静态链表L(把数组D中的数据存于L中)

char c[MAX_NUM_OF_KEY],c1[MAX_NUM_OF_KEY];

int i,j,max=D[0].key; // max为关键字的最大值

for(i=1;in;i++)

if(maxD[i].key)

max=D[i].key;

L.keynum=int(ceil(log10(max)));

L.recnum=n;

for(i=1;i=n;i++)

{

L.r[i].otheritems=D[i-1].otherinfo;

itoa(D[i-1].key,c,10); // 将10进制整型转化为字符型,存入c

for(j=strlen(c);jL.keynum;j++) // 若c的长度max的位数,在c前补'0'

{

strcpy(c1,"0");

strcat(c1,c);

strcpy(c,c1);

}

for(j=0;jL.keynum;j++)

L.r[i].keys[j]=c[L.keynum-1-j];

}

}

int ord(char c)

{ // 返回k的映射(个位整数)

return c-'0';

}

void Distribute(SLCell r[],int i,ArrType f,ArrType e) // 算法10.15

{ // 静态键表L的r域中记录已按(keys[0],…,keys[i-1])有序。本算法按

// 第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同。

// f[0..RADIX-1]和e[0..RADIX-1]分别指向各子表中第一个和最后一个记录

int j,p;

for(j=0;jRADIX;++j)

f[j]=0; // 各子表初始化为空表

for(p=r[0].next;p;p=r[p].next)

{

j=ord(r[p].keys[i]); // ord将记录中第i个关键字映射到[0..RADIX-1]

if(!f[j])

f[j]=p;

else

r[e[j]].next=p;

e[j]=p; // 将p所指的结点插入第j个子表中

}

}

int succ(int i)

{ // 求后继函数

return ++i;

}

void Collect(SLCell r[],ArrType f,ArrType e)

{ // 本算法按keys[i]自小至大地将f[0..RADIX-1]所指各子表依次链接成

// 一个链表,e[0..RADIX-1]为各子表的尾指针。算法10.16

int j,t;

for(j=0;!f[j];j=succ(j)); // 找第一个非空子表,succ为求后继函数

r[0].next=f[j];

t=e[j]; // r[0].next指向第一个非空子表中第一个结点

while(jRADIX-1)

{

for(j=succ(j);jRADIX-1!f[j];j=succ(j)); // 找下一个非空子表

if(f[j])

{ // 链接两个非空子表

r[t].next=f[j];

t=e[j];

}

}

r[t].next=0; // t指向最后一个非空子表中的最后一个结点

}

void printl(SLList L)

{ // 按链表输出静态链表

int i=L.r[0].next,j;

while(i)

{

for(j=L.keynum-1;j=0;j--)

printf("%c",L.r[i].keys[j]);

printf(" ");

i=L.r[i].next;

}

}

void RadixSort(SLList L)

{ // L是采用静态链表表示的顺序表。对L作基数排序,使得L成为按关键字

// 自小到大的有序静态链表,L.r[0]为头结点。算法10.17

int i;

ArrType f,e;

for(i=0;iL.recnum;++i)

L.r[i].next=i+1;

L.r[L.recnum].next=0; // 将L改造为静态链表

for(i=0;iL.keynum;++i)

{ // 按最低位优先依次对各关键字进行分配和收集

Distribute(L.r,i,f,e); // 第i趟分配

Collect(L.r,f,e); // 第i趟收集

printf("第%d趟收集后:\n",i+1);

printl(L);

printf("\n");

}

}

void print(SLList L)

{ // 按数组序号输出静态链表

int i,j;

printf("keynum=%d recnum=%d\n",L.keynum,L.recnum);

for(i=1;i=L.recnum;i++)

{

printf("keys=");

for(j=L.keynum-1;j=0;j--)

printf("%c",L.r[i].keys[j]);

printf(" otheritems=%d next=%d\n",L.r[i].otheritems,L.r[i].next);

}

}

void Sort(SLList L,int adr[]) // 改此句(类型)

{ // 求得adr[1..L.length],adr[i]为静态链表L的第i个最小记录的序号

int i=1,p=L.r[0].next;

while(p)

{

adr[i++]=p;

p=L.r[p].next;

}

}

void Rearrange(SLList L,int adr[]) // 改此句(类型)

{ // adr给出静态链表L的有序次序,即L.r[adr[i]]是第i小的记录。

// 本算法按adr重排L.r,使其有序。算法10.18(L的类型有变)

int i,j,k;

for(i=1;iL.recnum;++i) // 改此句(类型)

if(adr[i]!=i)

{

j=i;

L.r[0]=L.r[i]; // 暂存记录L.r[i]

while(adr[j]!=i)

{ // 调整L.r[adr[j]]的记录到位直到adr[j]=i为止

k=adr[j];

L.r[j]=L.r[k];

adr[j]=j;

j=k; // 记录按序到位

}

L.r[j]=L.r[0];

adr[j]=j;

}

}

#define N 10

void main()

{

RedType d[N]=,,,,,,,,,};

SLList l;

int *adr;

InitList(l,d,N);

printf("排序前(next域还没赋值):\n");

print(l);

RadixSort(l);

printf("排序后(静态链表):\n");

print(l);

adr=(int*)malloc((l.recnum)*sizeof(int));

Sort(l,adr);

Rearrange(l,adr);

printf("排序后(重排记录):\n");

print(l);

}

/*******************************************/

//归并排序

#includestdio.h

typedef int InfoType; // 定义其它数据项的类型

#define EQ(a,b) ((a)==(b))

#define LT(a,b) ((a)(b))

#define LQ(a,b) ((a)=(b))

#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度

typedef int KeyType; // 定义关键字类型为整型

struct RedType // 记录类型

{

KeyType key; // 关键字项

InfoType otherinfo; // 其它数据项,具体类型在主程中定义

};

struct SqList // 顺序表类型

{

RedType r[MAXSIZE+1]; // r[0]闲置或用作哨兵单元

int length; // 顺序表长度

};

void Merge(RedType SR[],RedType TR[],int i,int m,int n)

{ // 将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n] 算法10.12

int j,k,l;

for(j=m+1,k=i;i=mj=n;++k) // 将SR中记录由小到大地并入TR

if LQ(SR[i].key,SR[j].key)

TR[k]=SR[i++];

else

TR[k]=SR[j++];

if(i=m)

for(l=0;l=m-i;l++)

TR[k+l]=SR[i+l]; // 将剩余的SR[i..m]复制到TR

if(j=n)

for(l=0;l=n-j;l++)

TR[k+l]=SR[j+l]; // 将剩余的SR[j..n]复制到TR

}

void MSort(RedType SR[],RedType TR1[],int s, int t)

{ // 将SR[s..t]归并排序为TR1[s..t]。算法10.13

int m;

RedType TR2[MAXSIZE+1];

if(s==t)

TR1[s]=SR[s];

else

{

m=(s+t)/2; // 将SR[s..t]平分为SR[s..m]和SR[m+1..t]

MSort(SR,TR2,s,m); // 递归地将SR[s..m]归并为有序的TR2[s..m]

MSort(SR,TR2,m+1,t); // 递归地将SR[m+1..t]归并为有序的TR2[m+1..t]

Merge(TR2,TR1,s,m,t); // 将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t]

}

}

void MergeSort(SqList L)

{ // 对顺序表L作归并排序。算法10.14

MSort(L.r,L.r,1,L.length);

}

void print(SqList L)

{

int i;

for(i=1;i=L.length;i++)

printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);

printf("\n");

}

#define N 7

void main()

{

RedType d[N]=,,,,,,};

SqList l;

int i;

for(i=0;iN;i++)

l.r[i+1]=d[i];

l.length=N;

printf("排序前:\n");

print(l);

MergeSort(l);

printf("排序后:\n");

print(l);

}

/**********************************************/

//起泡排序

#includestring.h

#includectype.h

#includemalloc.h // malloc()等

#includelimits.h // INT_MAX等

#includestdio.h // EOF(=^Z或F6),NULL

#includestdlib.h // atoi()

#includeio.h // eof()

#includemath.h // floor(),ceil(),abs()

#includeprocess.h // exit()

#includeiostream.h // cout,cin

// 函数结果状态代码

#define TRUE 1

#define FALSE 0

#define OK 1

#define ERROR 0

#define INFEASIBLE -1

typedef int Status;

typedef int Boolean;

#define N 8

void bubble_sort(int a[],int n)

{ // 将a中整数序列重新排列成自小至大有序的整数序列(起泡排序)

int i,j,t;

Status change;

for(i=n-1,change=TRUE;i1change;--i)

{

change=FALSE;

for(j=0;ji;++j)

if(a[j]a[j+1])

{

t=a[j];

a[j]=a[j+1];

a[j+1]=t;

change=TRUE;

}

}

}

void print(int r[],int n)

{

int i;

for(i=0;in;i++)

printf("%d ",r[i]);

printf("\n");

}

void main()

{

int d[N]=;

printf("排序前:\n");

print(d,N);

bubble_sort(d,N);

printf("排序后:\n");

print(d,N);

}

/****************************************************/

//简单选择排序

#includestdio.h

typedef int InfoType; // 定义其它数据项的类型

#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度

typedef int KeyType; // 定义关键字类型为整型

struct RedType // 记录类型

{

KeyType key; // 关键字项

InfoType otherinfo; // 其它数据项,具体类型在主程中定义

};

struct SqList // 顺序表类型

{

RedType r[MAXSIZE+1]; // r[0]闲置或用作哨兵单元

int length; // 顺序表长度

};

int SelectMinKey(SqList L,int i)

{ // 返回在L.r[i..L.length]中key最小的记录的序号

KeyType min;

int j,k;

k=i; // 设第i个为最小

min=L.r[i].key;

for(j=i+1;j=L.length;j++)

if(L.r[j].keymin) // 找到更小的

{

k=j;

min=L.r[j].key;

}

return k;

}

void SelectSort(SqList L)

{ // 对顺序表L作简单选择排序。算法10.9

int i,j;

RedType t;

for(i=1;iL.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)

{

int i;

for(i=1;i=L.length;i++)

printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);

printf("\n");

}

#define N 8

void main()

{

RedType d[N]=,,,,,,,};

SqList l;

int i;

for(i=0;iN;i++)

l.r[i+1]=d[i];

l.length=N;

printf("排序前:\n");

print(l);

SelectSort(l);

printf("排序后:\n");

print(l);

}

/************************************************/

//树形选择排序

#includestring.h

#includectype.h

#includemalloc.h // malloc()等

#includelimits.h // INT_MAX等

#includestdio.h // EOF(=^Z或F6),NULL

#includestdlib.h // atoi()

#includeio.h // eof()

#includemath.h // floor(),ceil(),abs()

#includeprocess.h // exit()

#includeiostream.h // cout,cin

// 函数结果状态代码

#define TRUE 1

#define FALSE 0

#define OK 1

#define ERROR 0

#define INFEASIBLE -1

typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等

typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE

typedef int InfoType; // 定义其它数据项的类型

#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度

typedef int KeyType; // 定义关键字类型为整型

struct RedType // 记录类型

{

KeyType key; // 关键字项

InfoType otherinfo; // 其它数据项,具体类型在主程中定义

};

struct SqList // 顺序表类型

{

RedType r[MAXSIZE+1]; // r[0]闲置或用作哨兵单元

int length; // 顺序表长度

};

void TreeSort(SqList L)

{ // 树形选择排序

int i,j,j1,k,k1,l,n=L.length;

RedType *t;

l=(int)ceil(log(n)/log(2))+1; // 完全二叉树的层数

k=(int)pow(2,l)-1; // l层完全二叉树的结点总数

k1=(int)pow(2,l-1)-1; // l-1层完全二叉树的结点总数

t=(RedType*)malloc(k*sizeof(RedType)); // 二叉树采用顺序存储结构

for(i=1;i=n;i++) // 将L.r赋给叶子结点

t[k1+i-1]=L.r[i];

for(i=k1+n;ik;i++) // 给多余的叶子的关键字赋无穷大

t[i].key=INT_MAX;

j1=k1;

j=k;

while(j1)

{ // 给非叶子结点赋值

for(i=j1;ij;i+=2)

t[i].keyt[i+1].key?(t[(i+1)/2-1]=t[i]):(t[(i+1)/2-1]=t[i+1]);

j=j1;

j1=(j1-1)/2;

}

for(i=0;in;i++)

{

L.r[i+1]=t[0]; // 将当前最小值赋给L.r[i]

j1=0;

for(j=1;jl;j++) // 沿树根找结点t[0]在叶子中的序号j1

t[2*j1+1].key==t[j1].key?(j1=2*j1+1):(j1=2*j1+2);

t[j1].key=INT_MAX;

while(j1)

{

j1=(j1+1)/2-1; // 序号为j1的结点的双亲结点序号

t[2*j1+1].key=t[2*j1+2].key?(t[j1]=t[2*j1+1]):(t[j1]=t[2*j1+2]);

}

}

free(t);

}

void print(SqList L)

{

int i;

for(i=1;i=L.length;i++)

printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);

printf("\n");

}

#define N 8

void main()

{

RedType d[N]=,,,,,,,};

SqList l;

int i;

for(i=0;iN;i++)

l.r[i+1]=d[i];

l.length=N;

printf("排序前:\n");

print(l);

TreeSort(l);

printf("排序后:\n");

print(l);

}

/****************************/

//堆排序

#includestdio.h

typedef int InfoType; // 定义其它数据项的类型

#define EQ(a,b) ((a)==(b))

#define LT(a,b) ((a)(b))

#define LQ(a,b) ((a)=(b))

#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度

typedef int KeyType; // 定义关键字类型为整型

struct RedType // 记录类型

{

KeyType key; // 关键字项

InfoType otherinfo; // 其它数据项,具体类型在主程中定义

};

struct SqList // 顺序表类型

{

RedType r[MAXSIZE+1]; // r[0]闲置或用作哨兵单元

int length; // 顺序表长度

};

typedef SqList HeapType; // 堆采用顺序表存储表示

void HeapAdjust(HeapType H,int s,int m) // 算法10.10

{ // 已知H.r[s..m]中记录的关键字除H.r[s].key之外均满足堆的定义,本函数

// 调整H.r[s]的关键字,使H.r[s..m]成为一个大顶堆(对其中记录的关键字而言)

RedType rc;

int j;

rc=H.r[s];

for(j=2*s;j=m;j*=2)

{ // 沿key较大的孩子结点向下筛选

if(jmLT(H.r[j].key,H.r[j+1].key))

++j; // j为key较大的记录的下标

if(!LT(rc.key,H.r[j].key))

break; // rc应插入在位置s上

H.r[s]=H.r[j];

s=j;

}

H.r[s]=rc; // 插入

}

void HeapSort(HeapType H)

{ // 对顺序表H进行堆排序。算法10.11

RedType t;

int i;

for(i=H.length/2;i0;--i) // 把H.r[1..H.length]建成大顶堆

HeapAdjust(H,i,H.length);

for(i=H.length;i1;--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)

{

int i;

for(i=1;i=H.length;i++)

printf("(%d,%d)",H.r[i].key,H.r[i].otherinfo);

printf("\n");

}

#define N 8

void main()

{

RedType d[N]=,,,,,,,};

HeapType h;

int i;

for(i=0;iN;i++)

h.r[i+1]=d[i];

h.length=N;

printf("排序前:\n");

print(h);

HeapSort(h);

printf("排序后:\n");

print(h);

}


网站栏目:c语言大顶堆函数 大顶堆数组
新闻来源:http://scyanting.com/article/dddshej.html