目录
数组
插入
public class charu {
//维护一个有序的数组,新插入一个数,将它插入到合适的位置
public static void sort(int a[]){
for(int i=1;i<a.length;i++){
int tmp=a[i];//待插入的数
int j=i-1;
while(j>=0&&a[j]>tmp){
a[j+1]=a[j];
j--;
}
a[j+1]=tmp;
System.out.println();
System.out.println("第"+i+"次");
for(int ii=0;ii<a.length;ii++){
System.out.printf("%d ",a[ii]);
}
}
}
}
堆排序
package paixu.shuzu;
public class dui {
public static void swap(int[] array, int index1, int index2) {
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
// 最大堆
public static void maxHeap(int[] array, int heapSieze, int index) {
int left = index * 2 + 1; // 左子节点
int right = index * 2 + 2; // 右子节点
int maxValue = index; // 暂时定在Index的位置就是最大值
// 如果左子节点的值,比当前最大的值大,就把最大值的位置换成左子节点的位置
if (left < heapSieze && array[left] > array[maxValue]) {
maxValue = left;
}
// 如果右子节点的值,比当前最大的值大,就把最大值的位置换成右子节点的位置
if (right < heapSieze && array[right] > array[maxValue]) {
maxValue = right;
}
// 如果不相等,说明啊,这个子节点的值有比自己大的,位置发生了交换了位置
if (maxValue != index) {
swap(array, index, maxValue); // 就要交换位置元素
// 交换完位置后还需要判断子节点是否打破了最大堆的性质。最大堆性质:两个子节点都比父节点小。
maxHeap(array, heapSieze, maxValue);
}
}
// 构建堆
public static void buildMaxHeap(int[] array) {
if (array == null || array.length == 1)
return;
// 堆的公式就是 int root = 2*i, int left = 2*i+1, int right = 2*i+2;
int cursor = array.length / 2;
for (int i = cursor; i >= 0; i--) { // 这样for循环下,就可以第一次排序完成
maxHeap(array, array.length, i);
}
}
public static void sort(int[] array) {
if (array == null || array.length == 1)
return;
buildMaxHeap(array); // 第一次排序,构建最大堆,只保证了堆顶元素是数组里最大的
for (int i = array.length - 1; i >= 1; i--) {
// 这个是什么意思呢?,经过上面的一些列操作,目前array[0]是当前数组里最大的元素,需要和末尾的元素交换
// 然后,拿出最大的元素
swap(array, 0, i);
// 交换完后,下次遍历的时候,就应该跳过最后一个元素,也就是最大的那个值,然后开始重新构建最大堆
// 堆的大小就减去1,然后从0的位置开始最大堆
maxHeap(array, i, 0);
}
}
}
归并
package paixu.shuzu;
public class guibing {
//先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架
//再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,
// 再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。
public static void sort(int a[],int left,int right,int tmp[]){
//o(n-1)
if(left<right){
int mid=(left+right)/2;
//向左递归
sort(a,left,mid,tmp);
//向右递归
sort(a,mid+1,right,tmp);
merge(a,left,mid,right,tmp);
}
}
//a排序原始数组
//left左边有序序列的初始索引
//mid中间索引
//right右边索引
//中转数组
public static void merge(int a[],int left,int mid,int right,int tmp[]){
int i=left;//左边有序序列的初始索引
int j=mid+1;//右边有序序列的初始索引
int t=0;//tmp数组的当前索引
//先把左右两边的数据按照规则填充到tmp数组,直到左右两边序列,有一边处理完毕为止
//把有剩余的一边的数据填充到tmp
//tmp填充到a
while(i<=mid&&j<=right){
if(a[i]<=a[j]){
tmp[t]=a[i];
t++;
i++;
}else{
tmp[t]=a[j];
t++;
j++;
}
}
while (i<=mid){
tmp[t]=a[i];
t++;
i++;
}
while (j<=right){
tmp[t]=a[j];
t++;
j++;
}
//将tmp元素拷贝到a
// 注意,不是每次都拷贝所有
t=0;
int tempLeft=left;
while(tempLeft<=right){
a[tempLeft]=tmp[t];
tempLeft++;
t++;
}
}
}
快速
package paixu.shuzu;
public class kuaisu {
//先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗
//快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,
// 通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],
// 然后递归地去 nums[lo..p-1] 和 nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了
public static void sort(int a[],int left,int right){
int l=left;
int r=right;
int pivot=a[(l+r)/2];
int tmp=0;
//while循环目的是让比pivot小的放左边,大的放右边
while(l<r){
while (a[l]<pivot){
l++;
}
//在mid右边找,找到小于等于a[mid]的值
while (a[r]>pivot){
r--;
}
//l>=r说明左右两的值,以及全部按照左边小于pivot,右边大于pivot排好序
if(l>=r){
break;
}
tmp=a[l];
a[l]=a[r];
a[r]=tmp;
//交换完,发现相等,为了避免陷入死循环
if(a[l]==pivot){
r--;
}
if(a[r]==pivot){
l++;
}
}
if(l==r){
l+=1;
r-=1;
}
if(left<r)
sort(a,left,r);
if(right>l)
sort(a,l,right);
}
}
冒泡
package paixu.shuzu;
public class maopao {
//0-N-1 两两比较,交换,使每一轮交换后最大值逐步移到最后
public static void sort(int a[]){
for(int i=0;i<a.length;i++){
for(int j=0;j<a.length-i-1;j++){
if(a[j]>a[j+1]){
int tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
}
}
System.out.println("第"+i+"次");
for(int ii=0;ii<a.length;ii++){
System.out.printf("%d ",a[ii]);
}
}
}
}
选择
package paixu.shuzu;
public class xuanze {
//0-N-1 找最小值,放到0位置
//1-N-1 找最小值,放到1位置
public static void sort(int a[]) {
for (int i = 0; i < a.length - 1; i++) {
int index = i;
for (int j = i + 1; j < a.length; j++) {
if (a[index] > a[j]) {
index = j;
}
}
if (index != i) {
int tmp = a[i];
a[i] = a[index];
a[index] = tmp;
}
}
}
}
链表
冒泡排序
class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
public class maopao {
public static ListNode bubbleSort(ListNode head){
if(head == null || head.next == null) //链表为空或者仅有单个结点
return head;
ListNode cur = null, tail = null;
cur = head;
while(cur.next != tail){
while(cur.next != tail){
if(cur.val > cur.next.val){
int tmp = cur.val;
cur.val = cur.next.val;
cur.next.val = tmp;
}
cur = cur.next;
}
tail = cur; //下一次遍历的尾结点是当前结点(仔细琢磨一下里面的道道)
cur = head; //遍历起始结点重置为头结点
}
return head;
}
}
归并
public class guibing {
//归并排序
public static ListNode mergeSort(ListNode head){
if(head == null || head.next == null) //空链表或者只有单个结点
return head;
ListNode slow = head, fast = head.next;
while(fast != null && fast.next != null){ //使用快慢指针寻找中间 结点
slow = slow.next;
fast = fast.next;
if(fast.next != null)
fast = fast.next;
}
ListNode ptr1 = slow.next;
slow.next = null;
ListNode tmp1 = mergeSort(head);
ListNode tmp2 = mergeSort(ptr1);
return merge(tmp1, tmp2);
}
public static ListNode merge(ListNode start1, ListNode start2){
ListNode header = new ListNode(-1);
ListNode pre = header;
ListNode ptr1 = start1, ptr2 = start2;
while(ptr1 != null && ptr2 != null){
if(ptr1.val <= ptr2.val){
pre.next = ptr1;
pre = ptr1;
ptr1 = ptr1.next;
}else{
pre.next = ptr2;
pre = ptr2;
ptr2 = ptr2.next;
}
}
while(ptr1 != null){
pre.next = ptr1;
pre = ptr1;
ptr1 = ptr1.next;
}
while(ptr2 != null){
pre.next = ptr2;
pre = ptr2;
ptr2 = ptr2.next;
}
return header.next;
}
}
快排
public class kuaipai {
//快速排序
public static void quickSort(ListNode begin, ListNode end){
if(begin == null || begin == end)
return;
ListNode index = paration(begin, end);
quickSort(begin, index);
quickSort(index.next, end);
}
/**
* 划分函数,以头结点值为基准元素进行划分
* @param begin
* @param end
* @return
*/
public static ListNode paration(ListNode begin, ListNode end){
if(begin == null || begin == end)
return begin;
int val = begin.val; //基准元素
ListNode index = begin, cur = begin.next;
while(cur != end){
if(cur.val < val){ //交换
index = index.next;
int tmp = cur.val;
cur.val = index.val;
index.val = tmp;
}
cur = cur.next;
}
begin.val = index.val;
index.val = val;
return index;
}
}