单链表的排序 快速排序 归并排序 quicksort mergesort

原理都很简单,关键是某些边界能否正确写对:

#include<iostream>
#include<stdio.h>

using namespace std;
class Node {
public:
  int val;
  Node* next;
  Node(int val = 0):val(val),next(NULL){
  }
};

Node* quicksort(Node* head, Node* tail) {

  Node *res1 = NULL, *res2 = NULL;
  Node *p1 = new Node(0), *p2 = new Node(0), *cur = head;
  Node *cur1 = p1, *cur2 = p2;
  Node *pivot = head;
  if (head == NULL || head->next == tail || head == tail)
    return head;

  cur = cur->next;
  while (cur != tail) {
    if(cur->val < pivot->val) {
      cur1->next = cur;
      cur1 = cur1->next;
    }
    else {
      cur2->next = cur;
      cur2 = cur2->next;
    }
    cur = cur->next;
  }
  cur1->next = pivot;
  pivot->next = p2->next;
  cur2->next = tail;

  res1 = quicksort(p1->next, pivot);
  res2 = quicksort(p2->next, tail);
  pivot->next = res2;
  delete p1, p2;

  return res1 == NULL ? pivot : res1;
}
Node* mergesort(Node* head) {
  Node *p1 = head, *p2 = NULL, *cur1 = head, *cur2 = head, *dummy = new Node(0), *cur = dummy, *res = NULL;

  if (head == NULL || head->next == NULL)
    return head;
  while (cur2 != NULL && cur2->next != NULL && cur2->next->next != NULL) {
    cur1 = cur1->next;
    cur2 = cur2->next->next;
  }
  p2 = cur1->next;
  cur1->next = NULL;

  cur1 = mergesort(p1);
  cur2 = mergesort(p2);

  while (cur1 && cur2) {
    if (cur1->val < cur2->val){
      cur->next = cur1;
      cur1 = cur1->next;
    }
    else {
      cur->next = cur2;
      cur2 = cur2->next;
    }
    cur = cur->next;
  }
  if (cur1)
    cur->next = cur1;
  else
    cur->next = cur2;
  res = dummy->next;
  delete dummy;
  return res;
}
int main() {

  //Node arr[] = {Node(9), Node(8), Node(7), Node(6), Node(5), Node(4), Node(3), Node(2), Node(1)};
  Node arr[] = {Node(1), Node(2), Node(3), Node(3), Node(5), Node(6), Node(7), Node(8), Node(9)};

  for (int i = 0; i < sizeof(arr) / sizeof(arr[0]) - 1; ++i)
    arr[i].next = &arr[i+1];

  //Node *res = quicksort(&arr[0], NULL);
  //res = quicksort(NULL, NULL);
  Node *res = mergesort(&arr[0]);
  return 0;
}

单链表的排序 快速排序 归并排序 quicksort mergesort,布布扣,bubuko.com

时间: 2024-12-26 08:43:56

单链表的排序 快速排序 归并排序 quicksort mergesort的相关文章

从单链表中删除最大的元素,单链表元素排序

public class LinkList { public Node head; public LinkList() { head = new Node(); head.next = null; } //尾插法 public void createByTail(int[] arr, int n) { Node tail = head; for(int i=0; i<n; i++) { Node c = new Node(arr[i]); tail.next = c; tail = c; } t

链表——单链表的排序

题目要求: 对单链表进行从小到大排序,要求时间复杂度O(N*logN),空间复杂度O(1): 思路: 因时间复杂度要求为O(N*logN),简单排序(时间复杂度为O(N*N))均不可用, 故可以考虑归并排序的思想,归并排序对数组操作空间复杂度为O(n),但对链表为O(1),因为每次只在merge函数中创建了一个辅助的链表头结点ListNode temp=new ListNode(0); 归并排序的一般步骤为: 1)将待排序数组(链表)取中点并一分为二: 2)递归地对左半部分进行归并排序: 3)递

写给自己看的单链表(4):快速排序

搬运自我的CSDN https://blog.csdn.net/u013213111/article/details/88670136 !!!Attention:以下操作中的单链表均带有头结点!!!参考了这三篇文章:单链表快速排序算法的实现单链表的快速排序单链表的快排实现快速排序的思路是:首先,选取一个pivot:然后以pivot作为基准,对待排序的数据进行分区,得到两个部分,一个部分的数据均小于pivot,另一个部分的数据均大于pivot,然后对这两个部分再进行之前的操作,直至排序完成.对数组

单链表的排序

单链表的逆序: 由于链表不同于数组一样,所以将排好序的结点放到另一个链表中去,然后再由头指针指向该链表. 1 void Link::Sort(Node * Head) { 2 3 Node * Root = NULL; // 头指针,作为一个新链表指针,将所有结点链接到这里 4 Node * Tail = NULL; // 尾指针 5 Node * pMin = NULL; // 作为待操作链表结点中最小结点的前驱 6 Node * min = NULL; // 最小结点的指针 7 Node *

单链表合并排序实现

原题是要实现两个已排序的单链表合并后还是已排序,但我在网上查了很多都无法直接实现.对于初学者给个算法是没多大用的,下面给出完整代码.主要思路就是先接尾再排序.而一般书是直接开始分情况if...else if...else嵌套排序.比较复杂. /*关键:两个有序单链表的合并:其实本程序可以实现任意两个单链表的合并排序,思想就是 *1.建两个链表2.合并两个链表3.对合并后的链表排序4.打印 *关键函数:linkDList 直接连接两个链表;selectsort 单链表的选择排序*/ #define

链表的排序(归并排序+快慢指针)

链表的排序有很多方式,这里记录一下归并排序,关键点2个: 归并排序的过程和快慢指针法找中间结点,直接上代码. class Solution { public: ListNode* sortList(ListNode* head) { if (!head || !head->next) return head; ListNode* slow = head, * fast = head->next; while (fast && fast->next) { slow = sl

数据结构单链表就地排序

void LinListSort(LinList<T> &L) { ListNode<T> *curr, *pre, *p, *q; p = L.head->next; //原单链表L.head->next = NULL; //新单链表 while(p != NULL) { curr = L.head->next; pre = L.head; while(curr != NULL && curr->data <= p->d

面试题 - 无序单链表,排序

有一个单链表,无序,给定一个值,将链表中小于这个值的节点放置于链表前面,节点之间相对顺序不变. 这个题目我是这样想的,我们遍历单链表,当遇到大于指定指的节点群后,再其后面查找小于指定值的节点群,然后交换两个节点群的位置. 思路有了,大致的代码: function LinkNode(data){ this.data = data; this.next = null; } function LinkList(data){ this.head = new LinkNode(data); } LinkL

Leetcode:Reorder List 单链表重排序

Given a singly linked list L: L0→L1→-→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→- You must do this in-place without altering the nodes' values. For example, Given {1,2,3,4}, reorder it to {1,4,2,3}. 分析:观察重排前和重排后的序列,发现单链表前半部分各元素的相对顺序保持不变,而后半部分逆序.因