文章目录

  • 排序算法
  • 排序算法总览
  • 1 选择排序
  • 2 冒泡排序
  • 3 快速排序
  • 4 二叉树排序
  • 5 插入排序
  • 6 堆排序


排序算法

排序算法总览

(图片百度滴昂…)

java 中文 拼音排序 java英文排序_System


java 中文 拼音排序 java英文排序_数组_02

1 选择排序

选一个数和数据进行比较:

int[] nums = { 32, 13, 45, 22 };
	for(int i = 1; i < nums.length; i++) {
		for(int j = 0; j < nums.length; j++) {
			if(nums[i] > nums[j]) {
				int temp = nums[j];
				nums[j] = nums[i];
				nums[i] = temp;
			}
		}
	}
	for(int num : nums) {
		System.out.print(num + " ");
	}

2 冒泡排序

相邻两个元素的比较:

int[] nums = { 32, 13, 45, 22 };
	for(int i = 0; i < nums.length-1; i++) {
		for(int j = 0; j < nums.length-1-i;j++) {
			if(nums[j] > nums[j+1]) {
				int temp;
				temp = nums[j];
				nums[j] = nums[j+1];
				nums[j+1] = temp;
			}
		}
	}
	for(int num : nums) {
		System.out.print(num + " ");
	}

例子:现有一堆英文字母的歌曲,要求按照首字母排序:

// 对英文歌曲的首字母排序 
// a-z  97-122    A-Z 65-90
		String[] musics = new String[] {
				"more and more","beautiful","Abstrat","welcome"};
		for(int i = 0; i < musics.length - 1; i++) {
			for(int j = 0; j < musics.length - 1 - i; j++) {
				// 比较首字母
				// 先取出j的首字母
				char ch_j = musics[j].charAt(0);
				// 统一转化为小写字母
				if(ch_j < 97) {
					ch_j = (char) (ch_j +32);
				}
				// 先取出j+1的首字母
				char ch_j1 = musics[j+1].charAt(0);
				
				if(ch_j1 < 97) {
					ch_j1 = (char) (ch_j1 +32);
				}
				if(ch_j > ch_j1) {
					String temp;
					temp = musics[j];
					musics[j] = musics[j+1];
					musics[j+1] = temp;
				}
			}
		}
		for(String string : musics) {
			System.out.print(string + ", ");
		}

3 快速排序

算法思想:基于分治的思想,是冒泡排序的改进型。首先在数组中选择一个基准点(该基准点的选取可能影响快速排序的效率,后面讲解选取的方法),然后分别从数组的两端扫描数组,设两个指示标志(lo指向起始位置,hi指向末尾),首先从后半部分开始,如果发现有元素比该基准点的值小,就交换lo和hi位置的值,然后从前半部分开始扫秒,发现有元素大于基准点的值,就交换lo和hi位置的值,如此往复循环,直到lo>=hi,然后把基准点的值放到hi这个位置。一次排序就完成了。以后采用递归的方式分别对前半部分和后半部分排序,当前半部分和后半部分均有序时该数组就自然有序了。

java 中文 拼音排序 java英文排序_System_03


代码如下:

public static int partition(int []array, int lo, int hi){
        //固定的切分方式
        int key = array[lo];
        while(lo < hi){
            while(array[hi] >= key && hi > lo){//从后半部分向前扫描
                hi--;
            }
            array[lo]=array[hi];
            while(array[lo]<=key&&hi>lo){ // 从前半部分向后扫描
                lo++;
            }
            array[hi]=array[lo];
        }
        array[hi]=key;
        return hi;
    }
    
    public static void sort(int[] array,int lo ,int hi){
        if(lo >= hi){
            return ;
        }
        int index = partition(array,lo,hi);
        sort(array,lo,index-1);
        sort(array,index+1,hi); 
    }

快速排序的优化:
对于基准位置的选取一般有三种方法:固定切分,随机切分和三取样切分。固定切分的效率并不是太好,随机切分是常用的一种切分,效率比较高,最坏情况下时间复杂度有可能为O(N2)。对于三数取中选择基准点是最理想的一种。

public static int partition(int []array, int lo, int hi) {
        //三数取中
        int mid = lo + (hi - lo) / 2;
        if(array[mid] > array[hi]) {
            swap(array[mid], array[hi]);
        }
        if(array[lo] > array[hi]){
            swap(array[lo], array[hi]);
        }
        if(array[mid] > array[lo]){
            swap(array[mid], array[lo]);
        }
        int key = array[lo];
        
        while(lo < hi){
            while(array[hi] >= key && hi > lo) {
                hi--;
            }
            array[lo] = array[hi];
            while(array[lo] <= key && hi > lo){
                lo++;
            }
            array[hi] = array[lo];
        }
        array[hi] = key;
        return hi;
    }
    
    public static void swap(int a, int b){
        int temp=a;
        a=b;
        b=temp;
    }
    public static void sort(int[] array, int lo, int hi){
        if(lo>=hi){
            return ;
        }
        int index = partition(array, lo, hi);
        sort(array,lo,index-1);
        sort(array,index+1,hi);
    }

快速排序在序列中元素很少时,效率将比较低,不比插入排序。因此一般在序列中元素很少时使用插入排序,这样可以提高整体效率。

4 二叉树排序

在计算机科学中,二叉树是每个结点最多有两个子树的树结构。二叉树由各种节点组成。
1.每个节点都可以有左子节点,右子节点
2.每一个节点都有一个值

二叉树的遍历:左序,中序,右序
左序即: 中间的数遍历后放在左边
中序即: 中间的数遍历后放在中间
右序即: 中间的数遍历后放在右边
插入数据,插入基本逻辑是,小、相同的放左边,大的放右边

package practice;

public class Tree {
	public Integer data; // 节点值
	public static Tree root; // 根节点(唯一个)
	public Tree father; // 父节点
	public Tree leftChild; // 左孩子
	public Tree rightChild; // 右子节点
	// 左树是否为空
	public boolean hasLeftChild() {
		return leftChild != null;
	}
	public boolean hasRightChild() {
		return rightChild != null;
	}
	/**
	 * 插入节点
	 * 先让data和root的值比较,小于0插入左边,大于0插入右边
	 * 递归思想
	 */
	public void insert(Integer data, Tree father) {
		if(data.compareTo(father.data) == 0) {
			return;
		}
		if(data.compareTo(father.data) < 0) {
			// 父节点没有左节点
			if(!father.hasLeftChild()) {
				father.leftChild = new Tree(); // 生成一个左节点
				father.leftChild.data = data; // 给左结点赋值
				father.leftChild.father = father; // 指定左结点的父亲
			} else {
				insert(data, father.leftChild);
			}
		}
		if(data.compareTo(father.data) > 0) {
			// 父节点没有左节点
			if(!father.hasRightChild()) {
				father.rightChild = new Tree(); 
				father.rightChild.data = data;
				father.rightChild.father = father; 
			} else {
				insert(data, father.rightChild);
			}
		}
	}
	/**
	 * 判断是否有树根,没有的话将数据添加到数根里
	 * 有树根的话调用insert的重载方法,判断插入到左子树还是右子树
	 * @param data
	 */
	public void insert(Integer data) {
		if(root == null) {
			root = new Tree();
			root.data = data;
			return;
		} else {
			insert(data,root);
		}
	}
	/**
	 * 遍历树中的集合
	 * @param args
	 */
	public void outputTree(Tree tree) {
		System.out.print(tree.data + " ");
		if(tree.hasLeftChild()) {
			outputTree(tree.leftChild);
		}
		if(tree.hasRightChild()) {
			outputTree(tree.rightChild);
		}
		
	}
	/**
	 * 找出树中最小值
	 * 找出最大值getmaxValue(tree.rightChild);
	 * @param args
	 */
	public void getminValue(Tree tree) {
		if(tree.hasLeftChild()){
            getminValue(tree.leftChild);
        }else{
            System.out.println("最小值"+tree.data);
        }
	}

	public static void main(String[] args) {
		Tree tree = new Tree();
		tree.insert(5);
		tree.insert(2);
		tree.insert(3);
		tree.insert(1);
		tree.insert(8);
		tree.insert(3);
		tree.outputTree(tree.root);
		System.out.println();
		tree.getminValue(tree.root);
	}
}

5 插入排序

插入排序算法:

  • 1、以数组的某一位作为分隔位,比如index=1,假设左面的都是有序的.
  • 2、将index位的数据拿出来,放到临时变量里,这时index位置就空出来了.
  • 3、从leftindex=index-1开始将左面的数据与当前index位的数据(即temp)进行比较,如果array[leftindex]>temp,则将array[leftindex]后移一位,即array[leftindex+1]=array[leftindex],此时leftindex就空出来了.
  • 4、再用index-2(即leftindex=leftindex-1)位的数据和temp比,重复步骤3,
  • 直到找到<=temp的数据或者比到了最左面(说明temp最小),停止比较,将temp放在当前空的位置上.
  • 5、index向后挪1,即index=index+1,temp=array[index],重复步骤2-4,直到index=array.length,排序结束,
  • 此时数组中的数据即为从小到大的顺序.
public class Insert {
	public int[] array;
	public Insert(int[] array) {
		this.array = array;
	}
	public void insertArray() {
		int i, j, temp;
		for(i = 1; i < array.length; i++) {
			if(array[i]<array[i-1]){
				temp = array[i];
				for(j = i - 1; j >= 0 && array[j] > temp; j--) {
					array[j+1] = array[j];
				}
				array[j+1] = temp;
			}
		}
		System.out.println(Arrays.toString(array));
	}

	public static void main(String[] args) {
		int[] array = {23,34,15,20};
		Insert insert = new Insert(array);
		insert.insertArray();
	}
}

6 堆排序

是一种特殊的树形数据结构,其每个节点都有一个值,通常提到的堆都是指一颗完全二叉树,根结点的值小于(或大于)两个子节点的值,同时,根节点的两个子树也分别是一个堆。

java 中文 拼音排序 java英文排序_System_04


堆排序就是利用堆(假设利用大顶堆)进行排序的方法。它的基本思想是,将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根节点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的 n-1 个序列重新构造成一个堆,这样就会得到 n 个元素中次大的值。如此反复执行,便能得到一个有序序列了。

堆排序的实现需要解决的两个关键问题:

(1)将一个无序序列构成一个堆。

(2)输出堆顶元素后,调整剩余元素成为一个新堆。

package practice;

import java.util.Arrays;

public class Heap {
	 /**
     * 构建大顶堆
     */
    public static void isHeap(int[] a, int i, int len) {
        int temp, j;
        temp = a[i];
        for(j = 2 * i; j < len; j *= 2) { // 沿关键字较大的孩子结点向下筛选
            if(j < len && a[j] < a[j + 1])
                ++j; // j为关键字中较大记录的下标
            if(temp >= a[j])
                break;
            a[i] = a[j];
            i = j;
        }
        a[i] = temp;
    }

    public static void heapSort(int[] a) {
        int i;
        for(i = a.length / 2 - 1; i >= 0; i--) {// 构建一个大顶堆
            isHeap(a, i, a.length - 1);
        }
        for(i = a.length - 1; i >= 0; i--) {// 将堆顶记录和当前未经排序子序列的最后一个记录交换
            int temp = a[0];
            a[0] = a[i];
            a[i] = temp;
            isHeap(a, 0, i - 1);// 将a中前i-1个记录重新调整为大顶堆
        }
    }

    public static void main(String[] args) {
        int a[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
        heapSort(a);
        System.out.println(Arrays.toString(a));
    }
}