归并排序之数组和链表
2017-04-25 13:49
417 查看
归并排序之数组篇
Step1: 合并两个有序的数组
void mergearray (int arr[] , int first , int mid , int last , int temp[]) { // temp数组是临时用来储存已经排好序的数组 int i = first , j = mid + 1 ; // i , j分别储存两个数组两部分的开头 int m = mid , n = last ; // m储存中间值,i部分的末尾;n储存末尾值,j部分的末尾 int k = 0 ; // 储存temp数组的的位置 while (i <= m && j <= n) { // 两部分数组都未遍历完的时候 if (arr[i] <= arr[j]) temp[k ++] = arr[i ++] ; else if (arr[i] > arr[j]) temp[k ++] = arr[j ++] ; } // i , j两部分数组至少有一个已经遍历完,如果遍历完,就不会进入while循环 while (i <= m) // 如果i部分数组还未遍历完 temp[k ++] = arr[i ++] ; while (j <= n) // 如果j部分数组还未遍历完 temp[k ++] = arr[j ++] ; for (int i = 0 ; i < k ; i ++) arr[first + i] = temp[i] ; // 将排好序的数组复制回原数组,因为temp数组是临时的 }
Step2: 将数组一分为二,不断递归
void mergesort (int arr[] , int first , int last , int temp[]) { if (first == last) return ; // 只有一个元素的时候,就是已经排好序的,直接返回 if (first < last) { int mid = (first + last) / 2 ; // 找到中间点 mergesort (arr , first , mid , temp) ; // 对左边排好序 mergesort (arr , mid + 1 , last , temp) ; // 对右边排好序 mergearray (arr , first , mid , last , temp) ; // 将左边,右边合并进入一个数组 } }
Step3: 实现更加人性化的接口(更方便客户使用)
bool mergeSort (int arr[] , int length) {
int* p = new int [length] ;
// 用作临时储存数组
if (p == NULL || length == 0) {
return false ;
}
mergesort (arr , 0 , length - 1 , p) ;
delete [] p ;
return true ;
}
归并排序之链表篇
[title3]有这样一个链表[/title3]
struct node {
int data;
struct node* next;
node(int data = 0, struct node* next = NULL) : data(data), next(next) {}
} ;
Step1: 将两个有序链表合并成一个链表
node* mergeSortedList (node* h1 , node* h2) { // 注意这里要返回链表指针作为参数,否则其他函数无法获得已经排好序的链表 node* newhead ; if (h1 == NULL) return h2 ; if (h2 == NULL) return h1 ; // 如果有一个链表为空,那么直接返回另外一个链表指针作为头即可 if (h1 -> data <= h2 -> data) { newhead = h1 ; h1 = h1 -> next ; } else { newhead = h2 ; h2 = h2 -> next ; } // 找到新的头指针,并且把那个向后移一个 node* temp = newhead ; // 防止newhead被修改 while (h1 && h2) { if (h1 -> data <= h2 -> data) { temp -> next = h1 ; temp = temp -> next ; h1 = h1 -> next ; } else { temp -> next = h2 ; temp = temp -> next ; h2 = h2 -> next ; } } // 如果h1没排完: while (h1) { temp -> next = h1 ; h1 = h1 -> next ; temp = temp -> next ; } // 如果h2没排完: while (h2) { temp -> next = h2 ; temp = temp -> next ; h2 = h2 -> next ; } return newhead ; }
Step2: 将链表一分为二(注意怎么找到链表的中间点)
node* mergeSort (node* head) { // 注意这里需要有返回值,原因是要在递归过程把结果传递下去 if (head == NULL || head -> next == NULL) return head ; // 如果是空,直接返回head node* fast = head , *slow = head ; while (fast -> next && fast -> next -> next) { fast = fast -> next -> next ; slow = slow -> next ; } // 利用fast的检索速度是slow的两倍来找到中间点 node* leftHead = head ; node* rightHead = slow -> next ; slow -> next = NULL ; // 十分十分重要的是,要把左边的尾巴断掉,即置空 leftHead = mergeSort (leftHead) ; // 排好左边链表 rightHead = mergeSort (rightHead) ; // 排好右边链表 return mergeSortedList (leftHead , rightHead) ; // 返回合并后的链表 }
相关文章推荐
- 归并排序--数组和链表的实现
- C/C++ 数组,链表排序(平均时间复杂度 O(nlogn))归并、快速、堆、希尔之归并排序
- 链表排序(冒泡、归并)
- 单链表的归并、快速排序 C++
- 单向链表归并排序
- 用链表排序(数组的初级运用链表实现)
- 怎样编写一个程序,把一个有序整数数组放到二叉树中? 编写实现链表排序的一种算法。说明为什么你会选择用这样的方法?
- Merge Sorted Array 归并已排序的数组
- 两个已排序数组的归并
- 实现一个简单的c++ list容器(含sort排序 链表归并算法实现)
- 快速排序(数组和链表版本)
- 链表的各种操作实现 链表逆序 链表排序 有序链表归并 链表存在环的判定
- 学生类封装 , (链表)插入排序成绩 无动态数组 ,动态开辟空间 以及静态函数,数据成员的使用
- 两路归并的数组和链表实现
- POJ 2299 Ultra-QuickSort 【归并排序 || 树状数组求逆序对数】
- SortedList排序列表 算法实现 -- (实现了两个有序链表的归并排序功能)
- 链表的各种操作实现 链表逆序 链表排序 有序链表归并 链表存在环的判定
- {希尔排序、快速排序、动态数组、单链表、字符串转整型}大综合
- 链表节点合并排序:数组和单链表
- 数据结构 29 排序 自己实现 插入排序 插入和归并综合排序 给链表排序