cpp 排序算法

插入排序

链表的插入排序

(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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值