1.直接插入排序
public static void insertSort(int[] a) {
int length = a.length;//数组长度(提高速度)
int insertNum;//要插入的数
for (int i = 1; i < length; i++) {
insertNum = a[i];
int j = i-1;//已经排序好的元素个数
while (j >= 0 && a[j] > insertNum) {
a[j+1] = a[j];//元素移动一格
j--;
}
a[j+1] = insertNum;//将需要插入的数放在要插入的位置
}
}
2.归并排序
void mergearray(int a[], int first, int mid, int last, int temp[])
{
int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;
while (i <= m && j <= n)
{
if (a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while (i <= m)
temp[k++] = a[i++];
while (j <= n)
temp[k++] = a[j++];
for (i = 0; i < k; i++)
a[first + i] = temp[i];
}
void merge_sort(int a[], int first, int last, int temp[])
{
if (first < last)
{
int mid = (first + last) / 2;
merge_sort(a, first, mid, temp); //左边有序
merge_sort(a, mid + 1, last, temp); //右边有序
mergearray(a, first, mid, last, temp); //再将二个有序数列合并
}
3.快速排序
public static void quickSort(int[] a, int left, int right) {
int i = left, j = right;
int temp = a[left];//取第一个元素作为标准数据元素
while (i < j) {
//在数组右端扫描
while (i < j && temp <= a[j]) {
j--;
}
if (i < j) {
a[i++] = a[j];
}
//在数组左端扫描
while (i < j && temp > a[i]) {
i++;
}
if (i < j) {
a[j--] = a[i];
}
}
a[i] = temp;
//对左端集合排序
if (left < i) {
quickSort(a, left, i-1);
}
//对右端集合排序
if (i < right) {
quickSort(a, j+1, right);
}
}
4.选择排序
public static void selectSort(int[] a) {
int length = a.length;
for (int i = 0; i < length; i++) {//循环次数
int key = a[i];
int position = i;
for (int j = i+1; j < length; j++) {//选出最小的值和位置
if (a[j] < key) {
key = a[j];
position = j;
}
}
a[position] = a[i];//交换位置
a[i] = key;
}
}
5.希尔排序
void shellSort(int a[])
{
int j, temp; //d为增量
for(int d = a.length/2;d >= 1;d = d/2) //增量递减到1使完成排序
{
for(int i = d; i < a.length;i++) //插入排序的一轮
{
temp = a[i];
for(j = i - d;(j >= 0) && (a[j] > temp);j = j-d)
{
a[j + d] = a[j];
}
a[j + d] = temp;
}
}
}
或者
public void shellSort(int[] a){
int d = a.length;
while (d != 0) {
d = d/2;
for (int x = 0; x < d; x++) {//分的组数
for (int i = x+d; i < a.length; i+=d) {//组中的元素,从第二个数字开始
int j = i - d;//有序序列最后一位的位数
int temp = a[i];//要插入的元素
//从后往前遍历
for (; j >= 0 && temp < a[j]; j-=d) {
a[j+d] = a[j];
}
a[j+d] = temp;
}
}
}
}
6.冒泡排序
public void BubbleSort(int[] a) {
int temp;
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - i -1; j++) {
if (a[j] > a[j+1]) {
temp = a[j];//升序
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
优化后的冒泡排序
/**
* 优化一:如果某一轮两两比较中没有任何元素交换,这说明已经都排好序了
* ,算法结束,可以使用一个Flag做标记,默认为false,如果发生交互则
* 置为true,每轮结束时检测Flag,如果为true则继续,如果为false则返回。
* /
public void bubbleSort(int[] nums) {
if (nums == null || nums.length<=1) {
return;
}
//使用一个数记录尾边界
int length = nums.length;
boolean flag = true;//发生交换为true,否组false,第一次默认为true
while (flag) {
flag = false;//每次开始,设置其为未排序过
for (int i = 0; i < length; i++) {
if (nums[i-1] > nums[i]) {
int temp = nums[i-1];
nums[i-1] = nums[i];
nums[i] = temp;
//表示交换过数据
flag = true;
}
}
length--;//减小排序尾边界
}
}
进一步优化后的冒泡
优化二:某一轮结束位置为j,但是这一轮的最后一次交换发生在lastSwap的位置,
则lastSwap到j之间是排好序的,下一轮的结束点就不必是j–了
,而直接到lastSwap即可
public void bubbleSort(int[] nums) {
int j,k;
int flag = nums.length;//记录最后交换的位置(尾边界)
while (flag > 0) {//排序未结束
k = flag;//k记录尾边界
flag = 0;
for (j = 1; j < k; j++) {
if (nums[j-1]>nums[j]) {
int temp = nums[j-1];
nums[j-1] = nums[j];
nums[j] = temp;
//表示交换过数据
flag = j;//记录最新尾边界
}
}
}
}
7.堆排序(基于完全二叉树左子树当前父节点*2+1, 右子树当前父节点*2+26)
/*
* * @param array 完全二叉树
* @param h 当前父节点位置
* @param size 节点总数
*/
public void createHeap(int[] a, int n, int h) {
int i, j, flag, temp;
i = h; //i为要建堆的二叉树根节点下标
j = 2 * i + 1;//j为i的左孩子节点的下标
temp = a[i];
flag = 0;
//沿左右孩子中值较大者重复向下筛选
while (j < n && flag != 1) {
//寻找左右孩子中的较大者
if (j < n-1 && a[j]<a[j+1] ) {
j++;
}
if (temp > a[j]) {
flag = 1;//标记结束,筛选条件
}else { //否则把a[j]上移
a[i] = a[j];
i = j;
j = 2 *i + 1;
}
}
a[i] = temp;
}
public void initCreateHeap(int[] a, int n) {
//把数组元素a[0]~a[n-1]初始化创建为最大对
for (int i = (n-2)/2; i >= 0; i--) {
createHeap(a, n, i);
}
}
public void heapSort(int[] a, int n){
//用堆排序对数组元素a[0]~a[n-1]进行排序
int temp;
initCreateHeap(a, n);//初始创建最大对
for (int i = n - 1; i > 0; i--) {//当前最大对每次个数-1
//吧栈顶a[0]元素和当前最大对最后一个元素交换
temp = a[0];
a[0] = a[i];
a[i] = temp;
createHeap(a, i, 0);//调整根节点(下标为0,自二叉树个数为i)满足最大对
}
}
- 桶排序(基数排序):
public static void sort(int[] a) {
//首先确定排序的躺输
int max = a[0];
for (int i = 1; i < a.length; i++) {
if (a[i] > max) {
max = a[i];
}
}
int time = 0;
//判断位数
while (max > 0) {
max/=10;
time++;
}
//建立10个队列
List<ArrayList> queue = new ArrayList<>();
for (int i = 0; i < 10; i++) {
ArrayList<Integer> queue1 = new ArrayList<>();
queue.add(queue1);
}
//进行time次分配和收集
for (int i = 0; i < time; i++) {
//分配数组元素
for (int j = 0; j < a.length; j++) {
//得到数字的第time+1位数
int x = a[j] %(int)Math.pow(10, i+1)/(int)Math.pow(10, i);
ArrayList<Integer> queue2 = new ArrayList<>();
queue2.add(a[j]);
queue.set(x, queue2);
}
int count = 0;//元素计数器
for (int k = 0; k < 10; k++) {
while (queue.get(k).size()>0) {
ArrayList<Integer> queue3 = new ArrayList<>();
a[count] = queue3.get(0);
queue3.remove(0);
count++;
}
}
}
}