当前位置 博文首页 > L_add的博客:堆(堆排序)---完全二叉树

    L_add的博客:堆(堆排序)---完全二叉树

    作者:[db:作者] 时间:2021-08-27 10:02

    (一)堆
    1、定义:堆(heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。
    在这里插入图片描述
    假设父亲的下标是parent
    leftchild = parent * 2+1
    rightchild = parent * 2+2

    2、性质
    a.堆中某个结点的值总是不大于或不小于其父结点的值;
    b.堆总是一棵完全二叉树。
    (二)分类
    1、小根堆:父亲小于等于孩子
    2、大根堆:父亲大于等于孩子
    在这里插入图片描述
    (三)实现堆排序(小堆)

    在这里插入图片描述

    void Swap(int* a,int* b)
    {
    	int tmp = *a;
    	*a = *b;
    	*b = tmp;
    }
    void ADJustDown(int* a,int n,int parent)
    {
    	int child = parent * 2 + 1;
    	while(child < n)
    	{
    		//选出左右孩子中小的那个
    		if(child + 1 < n && a[child - 1] < a[child])//看数组是否越界
    			child ++;
    		if(a[child] < a[parent])
    		{
    			Swap(&a[parent],&a[child]);
    			parent = child;
    			child = parent * 2 + 1;
    		}
    		else
    			break;
    	}
    }
    int main()
    {
    	int a[] = {27,15,19,18,28,34,65,49,25,37};
    	int n = sizeof(a)/sizeof(a[0]);
    	ADJustDown(a,n,0);
    	return 0;
    }
    
    
    
    
    

    问题:左右子树不是小堆怎么办?

    在这里插入图片描述

    void Swap(int* a,int* b)
    {
    	int tmp = *a;
    	*a = *b;
    	*b = tmp;
    }
    void ADJustDown(int* a,int n,int parent)
    {
    	int child = parent * 2 + 1;
    	while(child < n)
    	{
    		//选出左右孩子中小的那个
    		if(child + 1 < n && a[child - 1] < a[child])//看数组是否越界
    			child ++;
    		if(a[child] < a[parent])
    		{
    			Swap(&a[parent],&a[child]);
    			parent = child;
    			child = parent * 2 + 1;
    		}
    		else
    			break;
    	}
    }
    int main()
    {
    	int a[] = {15,18,28,34,65,19,49,25,37,27};//最大下标为n-1
    	int n = sizeof(a)/sizeof(a[0]);
    	//建堆
    	for(int i = (n-1-1) / 2;i >= 0;i--)
    		ADJustDown(a,n,0);
    	return 0;
    }
    
    
    

    在这里插入图片描述

    #include<stdio.h>
    
    void Swap(int* p1, int* p2)
    {
    	int tmp = *p1;
    	*p1 = *p2;
    	*p2 = tmp;
    }
    
    void AdjustDown(int* a, int n, int parent)
    {
    	int child = parent * 2 + 1;
    	while (child < n){
    	
    		if (child+1 < n && a[child+1] > a[child]){
    			++child;
    		}
    
    		if (a[child] > a[parent]){
    			Swap(&a[parent], &a[child]);
    			parent = child;
    			child = parent * 2 + 1;
    		}
    		else{
    			break;
    		}
    	}
    }
    
    // 排升序,建大堆,还是小堆呢?-》大堆
    void HeapSort(int* a, int n)
    {
    	// 建堆 -》 时间复杂度是多少?O(N) 
    	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
    	{
    		AdjustDown(a, n, i);
    	}
    
    	int end = n - 1;
    	while (end > 0)
    	{
    		Swap(&a[0], &a[end]);
    		// 选出次大的
    		AdjustDown(a, end, 0);
    		--end;
    	}
    }
    
    int main()
    {
    
    	int a[] = { 15, 18, 28, 34, 65, 19, 49, 25, 37, 27 };
    	int n = sizeof(a) / sizeof(a[0]);
    	HeapSort(a, n);
    
    	return 0;
    }
    
    cs
    下一篇:没有了