基础算法3_选择排序(简单选择排序+堆排序)

基本思想:选择排序 顾名思义就是要进行选择,如对9 6 11 7 进行排序,第一趟排序从这四个数中选出最小的数7 排在第一个 接下来就从剩余的三个数中选择最小的一个 那么选择排序基本就是这个思想。

1.简单选择排序(直接看代码)

	//核心算法
	//A是待排序数组 n是表长
	public void SelectSort(int[] A,int n ){
		int i,j,min;//min用于在待排序元素中找到最小位置的元素
		//最后一个元素不用选择了
		for(i=0;i<n-1;i++){
			min=i;
			for(j=i+1;j<n;j++){
				if(A[j]<A[min]) 
					min=j;//找最小元素位置
			}
			//交换位置(想想冒泡排序的交换)
			if (min!=i) {
				int temp=A[i];
				A[i]=A[min];
				A[min]=temp;
			}
		}
	}

2.堆排序(在交换排序中是比较重要的一种算法了 是一种树形排序结构)

堆分为大顶堆和小顶堆,以大顶堆为例,大顶堆可以看成是一棵完全二叉树的结构,大顶堆的堆顶比起左子树和右子树的数都大,因此我们要理解好大顶堆就首先要理解什么是二叉树?进一步理解什么是排序二叉树?什么是完全二叉树?

二叉树:就是其分支最多为2的树 如以下四种情况

  

排序二叉树:A结点的左子树所有数都比A小,A结点的右子树所有数都比A大

完全二叉树:看一个图来理解

(百度上的)完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。

在简单回顾了这些内容后,就是来了解堆排序了,

1》. 构造一个初始堆(n=5)

2》进行反复筛选调整 建立大顶堆(核心就在此)

     2.1从有孩子的结点开始从后向前进行调整。由完全二叉树的性质,二叉树的最后一个有孩子结点是n/2(向下取整)

再举个例子 进一步巩固

所以堆排序的核心就在于将有孩子的结点与其左右孩子进行比较 交换 再不断进行调整

看代码:

public class Sort7 {
	//建立大根堆
	public void BuildMaxHeap(int A[],int n){
		//从有孩子的结点开始从后向前进行调整
		for(int i=n/2;i>0;i--){
			adjustDown(A,i,n);
		}
	}
	//核心算法
	public void adjustDown(int A[],int k,int n){
		int i,j;
		//将k处结点向下调整 A[0]元素用于暂存
		A[0]=A[k];
		for(i=2*k;i<=n;i=i*2){
			//1.找出k结点左右孩子的最大值 左孩子结点位置数为偶数 右孩子为奇数
			if(i<n&&A[i]<A[i+1]){
				//右孩子大于左孩子
				i++;
			}
			//2.将k结点和左右孩子中的最大值进行比较
			    //2.1 若k结点大于其最大值 不交换 本次筛选结束 进行下一个节点的调整
			if(A[i]<=A[0]) break;
			else{
				//2.2若k结点小于其最大值进行交换
				A[k]=A[i];//交换
				k=i;//交换后可能会破坏大顶堆 所以进行向下调整
			}
		}
		//3.将k结点放在最终位置上
		A[k]=A[0];	
	}
	
	//快速排序
	void HeapSort(int A[],int n){
		BuildMaxHeap(A, n);//建堆
		for(int i=n;i>1;i--){
			//将大顶堆的堆顶元素输出:先将堆顶元素与最后一个元素交换,然后再调整大顶堆
			int temp=A[1];
			A[1]=A[i];
			A[i]=temp;
			adjustDown(A, 1, i-1);
		}
		
		
	}
	//A是待排序数组 n是表长
	public void insertSort(int[] A,int n ){
		int i,j;
		for(i=2;i<=n;i++){
			//待插入的数据A[i]大于A[i-1],则直接插入,反之则往前进行比较,
			//选择合适的插入的位置
			if(A[i]<A[i-1]){
				//A[0]仅是哨兵
				A[0]=A[i];
				//边查找边移动位置
				for(j=i-1;A[i]<A[j];j--){
					A[j+1]=A[j];
				}
				//找到插入位置
				A[j+1]=A[0];
			}
		}
	}

	//测试
    public static void main(String[] args) {
    	int[] A={0,2,12,6,8,11,31,18,27};
    	int n =A.length-1;
    	InsertSort7 insertSort = new InsertSort7();
    	insertSort.HeapSort(A, n);
    	for(int i=0;i<=n;i++){
    		System.out.println(A[i]);
    	}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值