插入排序
链表的插入排序
(1) Insertion Sort List - LeetCode
算法策略:
链表分有序+无序,依次从无序数组中移除元素,插入业已有序的链表中的正确位置直至无序链表为空。
复杂度分析:
n轮处理:
移除-O(1),
查找有序链表中的正确位置:在左边的前驱链表查找时最好情况下O(1),对应链表完全逆序的情况(这与数组的插入排序不同,因为单链表是由左向右开始查找),最坏情况O(n)
插入-O(1)
总体:最好情况-O(n),最坏O-(n),平均-O(n)
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
if(head==NULL || head->next==NULL) return head;
//链表所含元素n>=2
ListNode* newHead = new ListNode(-1);//哑节点防止插入位置在开头(完全逆序)的情况
newHead->next = head;//初始仅一个元素时链表已有序
ListNode* oldHead = head->next;
head->next = NULL;//断成新旧两链
ListNode* cur = newHead;
while(oldHead){//旧链元素未处理完
while(cur->next && cur->next->val <= oldHead->val){//查找
cur = cur->next;
}//cur指向插入位置的前驱
//插入
ListNode* next = oldHead->next;
oldHead->next = cur->next;
cur->next = oldHead;
cur = newHead;
oldHead = next;
}
return newHead->next;
}
};
选择排序
链表
算法策略:
链表分有序无序,从无序链表中查找当前无序链表中的max,移除后插入业已有序且元素都在最终位置的有序链表末尾
复杂度分析:
查找max-与链表顺序无关,一次查找始终都要O(n)
插入、移除:O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
struct maxInfo{
ListNode* maxnode;
ListNode* maxprev;
};
class Solution {
public:
maxInfo* selectMax(ListNode* head){
maxInfo* Max = new maxInfo{head,NULL};
ListNode* cur = head;
ListNode* prev = NULL;
while(cur){
if(Max->maxnode->val <= cur->val){
Max->maxnode = cur;
Max->maxprev = prev;
}
prev = cur;
cur = cur->next;
}
return Max;
}
//使用selectinSort
ListNode* sortList(ListNode* head) {
ListNode* newHead = new ListNode(-1);//哑节点
newHead->next = NULL;
ListNode* tail = newHead;
while(head){
maxInfo* Max = selectMax(head);//查找max及其前驱
if(Max->maxprev==NULL){
head = Max->maxnode->next;
}
else{
Max->maxprev->next =Max->maxnode->next;
}
//插入
Max->maxnode->next = tail->next;
tail->next =Max->maxnode;
}
return newHead->next;
}
};
归并排序
链表
算法策略:
链表一分为二list1&list2,让递归函数对list1和list2进行归并排序,然后合并链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* merge(ListNode* list1,ListNode* list2){
ListNode* newHead = new ListNode(-1);
newHead->next = NULL;
ListNode* tail = newHead;
while(list1 && list2){
if(list1->val <= list2->val){
tail->next = list1;
tail = tail->next;
list1 = list1->next;
}
else{
tail->next = list2;
tail = tail->next;
list2 = list2->next;
}
}
while(list1){
tail->next = list1;
tail = tail->next;
list1 = list1->next;
}
while(list2){
tail->next = list2;
tail = tail->next;
list2 = list2->next;
}
return newHead->next;
}
//使用归并排序
ListNode* sortList(ListNode* head) {
if(head==NULL || head->next==NULL){//递归基
return head;
}
//链表一分为二
ListNode* list1 = head;
//找中点
ListNode* prev = NULL;//记录list2的前驱方便断链
ListNode* slow = head;
ListNode* fast = head;
while(fast && fast->next){
prev = slow;
slow = slow->next;
fast =fast->next;
if(fast) fast = fast->next;
}
ListNode* list2 = slow;
prev->next = NULL;//断链
list1 = sortList(list1);
list2 = sortList(list2);//链表一定要记得返回头!
return merge(list1,list2);
}
};
bubbleSort
/*
输入n个整数,对它们进行排序,从大到小输出。0<n<=100。
*/
#include <iostream>
using namespace std;
void bubbleSort(int data[],int n);
void swap(int data[],int i,int j);
int main() {
int n;
cin >> n;
int data[n];
cout<<"请输入待排序数组:"<<endl;
for (int i = 0; i < n; i++) {
cin >> data[i];
}
//使用冒泡排序
bubbleSort(data,n);
cout<<"排序结果:"<<endl;
for (int i = 0; i < n; i++) {
cout<< data[i]<<" ";
}
}
//原地冒泡排序
void bubbleSort(int data[], int n) {
for (int begin = 0; begin < n - 1; begin++) {
int flag = 0;
for (int i = n - 1; i > begin; i--) {
if (data[i] > data[i - 1]) {
swap(data, i, i-1);
flag = 1;
}
}
if(flag==0){
break;
}
}
}
void swap(int data[], int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}