数组和链表的插入排序

2 篇文章 0 订阅

数组的插入排序

如果是数组的插入排序,则数组的前面部分是有序序列,每次找到有序序列后面的第一个元素(待插入元素)的插入位置,将有序序列中的插入位置后面的元素都往后移动一位,然后将待插入元素置于插入位置。

前文:排序算法_余生为莹的博客-CSDN博客

/**
	 * 插入排序:插入排序是一种简单直观的排序算法,插入排序在实现上,
	 * 		通常采用in-place排序(即只需用到O(1)的额外空间的排序),
	 * 		因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
	 * 步骤:
	 *	   1> 从第一个元素开始,该元素可以认为已经被排序
	 *	   2> 取出下一个元素,在已经排序的元素序列中从后向前扫描
	 *	   3> 如果该元素(已排序)大于新元素,将该元素移到下一位置
	 *	   4> 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
	 *	   5> 将新元素插入到该位置后
	 *	   6> 重复步骤2~5
	 *
     * 应用:	插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,
     * 		比如量级小于千,那么插入排序还是一个不错的选择。 插入排序在工业级库中也有着广泛的应用,
     * 		在STL的sort算法和stdlib的qsort算法中,都将插入排序作为快速排序的补充,
     * 		用于少量元素的排序(通常为8个或以下)
	 * @param array
	 */
	public void insertionSort(int[] array) {
		int l = array.length;
		for (int i = 1; i < l; i++){
			//先获取一个数据
	        int get = array[i];                
	        int j = i - 1;
	        //将获取的数据右向左进行比较
	        while (j >= 0 && array[j] > get){
	        	// 如果该手牌比抓到的牌大,就将其右移
	        	array[j + 1] = array[j];            
	            j--;
	        }
	        array[j + 1] = get; // 直到该手牌比抓到的牌小(或二者相等),将抓到的牌插入到该手牌右边(相等元素的相对次序未变,所以插入排序是稳定的)
	    }
	}

单链表的插入排序

对于链表而言,插入元素时只要更新相邻节点的指针即可,不需要像数组一样将插入位置后面的元素往后移动,因此插入操作的时间复杂度是 O(1),但是找到插入位置需要遍历链表中的节点,时间复杂度是 O(n),因此链表插入排序的总时间复杂度仍然是 O(n^2),其中 n是链表的长度。

对于单向链表而言,只有指向后一个节点的指针,因此需要从链表的头节点开始往后遍历链表中的节点,寻找插入位置。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode insertionSortList(ListNode head) {

        if(head==null){
            return null;
        }
        //创建哑节点:便于在head节点之前插入节点
        ListNode dummyHead=new ListNode(0);
        dummyHead.next=head;
        //创建lastSorted为链表已排序部分的最后一个节点并初始化
        ListNode lastSorted=head;
        //创建curr为待插入的元素并初始化
        ListNode curr=head.next;
        while(curr!=null){
            //如果lastSorted.val<=curr.val,说明curr应该位于lastSorted之后,将lastSorted后移一位,curr变成新的lastSorted
            if(lastSorted.val<=curr.val){
                lastSorted=lastSorted.next;
            }else{
                //否则,从链表的头结点开始往后遍历链表中的节点,寻找插入curr的位置。从链表头开始遍历,令pre为插入curr的前一个节点
                ListNode pre=dummyHead;
                while(pre.next.val<=curr.val){
                    pre=pre.next;
                }
                //对curr的插入
                lastSorted.next=curr.next;
                curr.next=pre.next;
                pre.next=curr;
            }
            //下一个待插入的元素
            curr=lastSorted.next;
        }
        return dummyHead.next;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值