自然归并排序和单链表实现的归并排序

本文介绍了一种自然归并排序算法及其实现,并探讨了单链表上的归并排序方法。自然归并排序利用数组中已有的有序子数组进行排序,而单链表归并排序则适用于链表数据结构。

自然归并排序

(1)思路:

1、找出需要排序数组中的所有有序子数组,将每个子数组的起始下标存在一个辅组数组中,假设为mark[]。

2、将有序字数组两两归并,最后得到有序数组。

3、需要注意被排序数组的长度N<=2的特殊情形。

(2)代码

public class NatureMerge extends Sort {
	public static <T extends Comparable<? super T>> int pass(T[] arr, int[] mark) {
		int j = 0;
		T temp = arr[0];
		mark[j++] = 0;
		for(int i = 1; i < arr.length; i++) {
			if(temp.compareTo(arr[i]) <= 0) temp = arr[i];
			else mark[j++] = i;
		}
		mark[j] = arr.length;
		return j;
	}
	
	public static <T extends Comparable<? super T>> void natureMerge(T[] arr, T[] aux, int[] mark) {
		int max = pass(arr, mark);
		
		for(int sz = 1; sz < max; sz += sz) {
			for(int i = 0; i < max - sz; i += sz + sz) {
				merge(arr, aux, mark[i], mark[i + sz] - 1, mark[Math.min(i + sz + sz, max)] - 1);
			}
		}
	}
	
	//要检查N<=2时的特殊境况
	@SuppressWarnings("unchecked")
	public static <T extends Comparable<? super T>> void sort(T[] a) {
		int N = a.length;
		if(N <= 1) return ;
		if(N == 2) if(less(a[1], a[0])) exch(a, 0, 1);
		int[] mark = new int[N];
		T[] aux = (T[])new Comparable[N];
		natureMerge(a, aux, mark);
	}
	
	private static <T extends Comparable<? super T>> void merge(T[] a, T[] aux, int lo, int mid, int hi) {
		for(int i = lo; i <= hi; i++) {
			aux[i] = a[i];
		}
		int j = lo;
		int k = mid + 1;
		for(int i = lo; i <= hi; i++) {
			if(j > mid) a[i] = aux[k++]; 
			else if(k > hi) a[i] = aux[j++];
			else if(less(aux[j], aux[k])) a[i] = aux[j++];
			else a[i] = aux[k++];
		}		
	}
	
	protected static <T extends Comparable<? super T>> boolean less(T v, T w) {
        return v.compareTo(w) < 0;
    }
	
	protected static <T extends Comparable<? super T>> void exch(T[] a, int i, int j) {
        T swap = a[i];
        a[i] = a[j];
        a[j] = swap;
    }
}

单链表归并排序

public static <T extends Comparable<? super T>> Node<T> sort(Node<T> list) {
		if(list == null || list.next == null) return list;
		Turple<Node<T>, Node<T>> t = getTwoLists(list);
		Node<T> l = sort(t.e1);
		Node<T> r = sort(t.e2);
		return merge(l, r);
	}
	
	public static <T extends Comparable<? super T>> Node<T> merge(Node<T> left, Node<T> right) {
		if(left == null) return right;
		if(right == null) return left;
		if(less(right.data, left.data)) {
			Node<T> temp = left;
			left = right;
			right = temp;
		}
		Node<T> lf = left;
		Node<T> rg = right;
		Node<T> temp = null;
		while(lf.next != null) {
			if(less(right.data, lf.next.data)) {
				while(rg.next != null && less(rg.next.data, lf.next.data)) {
					rg = rg.next;
				}
				temp = right;
				right = rg.next;
				rg.next = lf.next;
				lf.next = temp;
				if(right == null) break;
			}
			lf = lf.next;
		}
		if(lf.next == null) {
			lf.next = right;
		}
		return left;
	}
	
	public static <T extends Comparable<? super T>> Turple<Node<T>, Node<T>> getTwoLists(Node<T> list) {
		if(list.next == null) throw new ArrayIndexOutOfBoundsException();
		Node<T> p1 = list;
		Node<T> p2 = list;
		Node<T> temp = null;
		
		while(p2.next != null) {
			p2 = p2.next;
			if(p2.next != null) {
				p2 = p2.next;
			}
			temp = p1;
			p1 = p1.next;
		}
		temp.next = null;
		return new Turple<Node<T>, Node<T>>(list, p1);
	}


归并排序是一种高效的排序算法,其基本思想是分治法,即将待排序的序列分成若干个子序列,分别进行排序,然后将有序的子序列合并成一个有序的序列。使用单链表实现归并排序的递归版本可以分为以下几个步骤: 1. **分割链表**:将链表分成两半,找到链表的中间节点。 2. **递归排序**:对分割后的两个子链表分别进行归并排序。 3. **合并链表**:将两个有序的子链表合并成一个有序的链表。 下面是一个使用单链表实现归并排序的递归版本的示例代码: ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def find_middle(head): slow, fast = head, head.next while fast and fast.next: slow = slow.next fast = fast.next.next return slow def merge_sort(head): if head is None or head.next is None: return head # 分割链表 middle = find_middle(head) right_head = middle.next middle.next = None # 递归排序左右两部分 left = merge_sort(head) right = merge_sort(right_head) # 合并排序后的两部分 return merge(left, right) def merge(l1, l2): dummy = ListNode() tail = dummy while l1 and l2: if l1.val < l2.val: tail.next = l1 l1 = l1.next else: tail.next = l2 l2 = l2.next tail = tail.next tail.next = l1 or l2 return dummy.next def print_list(head): while head: print(head.val, end=' ') head = head.next print() # 示例使用 if __name__ == "__main__": head = ListNode(38) head.next = ListNode(27) head.next.next = ListNode(43) head.next.next.next = ListNode(3) head.next.next.next.next = ListNode(9) head.next.next.next.next.next = ListNode(82) head.next.next.next.next.next.next = ListNode(10) print("Original list:") print_list(head) sorted_head = merge_sort(head) print("Sorted list:") print_list(sorted_head) ``` 这个代码定义了一个`ListNode`类来表示链表节点,`find_middle`函数用于找到链表的中间节点,`merge_sort`函数实现归并排序的递归逻辑,`merge`函数用于合并两个有序的链表,`print_list`函数用于打印链表
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值