链表的快排和归并排序

1、对于数组排序,请最好使用快速排序

原理:

algorithm quicksort(A, lo, hi) is
    if lo < hi then
        p := partition(A, lo, hi)
        quicksort(A, lo, p – 1)
        quicksort(A, p + 1, hi)

algorithm partition(A, lo, hi) is
    pivot := A[hi]
    i := lo        // place for swapping
    for j := lo to hi – 1 do
        if A[j] ≤ pivot then
            swap A[i] with A[j]
            i := i + 1
    swap A[i] with A[hi]
    return i

The steps are:

Pick an element, called a pivot, from the array.
Partitioning: reorder the array so that all elements with values less than the pivot come before the pivot, while all elements with values greater than the pivot come after it (equal values can go either way). After this partitioning, the pivot is in its final position. This is called the partition operation.
Recursively apply the above steps to the sub-array of elements with smaller values and separately to the sub-array of elements with greater values.

范例:

class ArrayList : public List {
 public:
  ArrayList();
  ~ArrayList();
  virtual void sort(void);
 private:
  E* storage;
  int _size;
  int _maxsize;
  static const int extend_factor = 2;
  void extend(void);
};
static int partionsl(int *a, int first, int last) {
    int i = first;
    int j = first-1;
    for (i = first; i < last; i++) {
        if (a[i] < a[last]) {
            j++;
            swap(&a[i], &a[j]);
        }
    }
    swap(&a[j+1], &a[last]);
    return j+1;
}
static void quicksort(int* a, int first, int last) {
    if (last > first) {
        int m = partionsl(a, first, last);
        quicksort(a, first, m-1);
        quicksort(a, m+1, last);
    }
}
void ArrayList::sort(void) {
    quicksort(storage, 0, _size-1);
}

2、对于链表排序,请最好使用归并排序

原理:

MergeSort(li):
 if(li.size() > 1)
    split li into li1 and li2 at position li1.size()/2
    li1.sort()
    li2.sort()
    li.merge(li1,li2)
注意浅复制的应用,因为如果采用深复制运行mergeSort会产生大量内存副本,使得程序效率大幅度降低。

范例:

class LinkedList : virtual public List {
 public:
  typedef struct node {
    E data;
    struct node* next;
    struct node* prev;
    node(E data, struct node* next = NULL, struct node* prev = NULL)
        : data(data), next(next), prev(prev) {}
  } node;
  LinkedList();
  ~LinkedList();
  virtual void sort(void);
 private:
  node* head;
  node* tail;
  int _size;
};
void LinkedList::sort(void) {
  if (this->size() > 1) {
    node* fast = this->head;
    node* slow = this->head;
    LinkedList li_left;
    LinkedList li_right;

    li_left.head = this->head;
    while (fast != NULL && fast->next != NULL) {
      li_left._size++;
      fast = fast->next->next;
      slow = slow->next;
    }
    li_left.tail = slow->prev;
    li_left.tail->next = NULL;

    li_right.head = slow;
    li_right.head->prev = NULL;
    li_right.tail = this->tail;
    li_right._size = this->_size - li_left._size;

    this->head = NULL;
    this->tail = NULL;

    li_left.sort();
    li_right.sort();

    node* pointer_left = li_left.head;
    node* pointer_right = li_right.head;

    node* pointer_head = NULL;
    node* pointer_tail = NULL;

    while (pointer_left != NULL && pointer_right != NULL) {
      node* temp;
      if (pointer_left->data <= pointer_right->data) {
        temp = pointer_left;
        pointer_left = pointer_left->next;
      } else {
        temp = pointer_right;
        pointer_right = pointer_right->next;
      }
      if (pointer_head == NULL) {
        pointer_head = pointer_tail = temp;
      } else {
        pointer_tail->next = temp;
        temp->prev = pointer_tail;
        pointer_tail = temp;
      }
      pointer_head->prev = NULL;
      pointer_tail->next = NULL;
    }

    while (pointer_left != NULL) {
      pointer_tail->next = pointer_left;
      pointer_left->prev = pointer_tail;
      pointer_tail = pointer_left;
      pointer_left = pointer_left->next;
    }

    while (pointer_right != NULL) {
      pointer_tail->next = pointer_right;
      pointer_right->prev = pointer_tail;
      pointer_tail = pointer_right;
      pointer_right = pointer_right->next;
    }

    this->head = pointer_head;
    this->tail = pointer_tail;

    li_left.head = li_left.tail = NULL;
    li_right.head = li_right.tail = NULL;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值