链表的快排和归并排序

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

你可能感兴趣的:(链表)