数据结构_栈及栈的应用非递归快速排序

一、顺序栈

  • 除了出栈操作之外,所有运算都是O(1)
  • 进栈运算在最坏情况下的时间复杂度为O(n)。(需要doubleSpace
  • 但是广义上来说插入运算还是常量的时间复杂度

1.1 顺序栈cpp数据结构


template <class elemType>
class stack {
    public: 
        virtual bool isEmpty() const = 0; 
        virtual void push(const elemType &x) = 0; 
        virtual elemType pop() = 0;              
        virtual elemType top() const = 0;
        // 虚析构函数防止内存泄漏
        virtual ~stack() {}
}; 


template <class elemType>
class seqStack: public stack<elemType>{
private:
    elemtype *elem;
    int top_p;
    int maxSize;
    void doubleSpace();
public:
    seqStack(int initSize = 10);
    ~seqStack() { delete [] elem; }
    bool isEmpty() const { return top_p == -1; }
    void push(const elemType &x);
    elemtype pop() { return elem[top_p--]; }
    elemType top() const { return emel[top_p]; } 
}

template <class elemType>
seqStack<elemType>::seqStack(int initSize){
    elem = new elemType[initSize];
    maxSize = initSize ;
    top_p = -1;  
}

template <class elemtype>
void seqStack<elemType>:: push(const elemtype &x) {
    if (top_p == maxSize - 1)
        doubleSpace();
    elem[++top_p] = x;
}


template <class elemtype>
void seqStack<elemType>:: doubleSpace(){
    maxSize = maxSize * 2;
    telemtype * tmp = elem;
    elem = new elemType[maxSize];
    int i = 0;
    while(i <= top_p)
        elem[i] = tmp[i];
        i += 1;
    delete tmp;
}

1.2 单链栈

1.2.1 单链栈CPP


template <class T>
class linkStack: public stack<T> {
private:
    struct node {
        T data;
        node *next;
        node(const T &x, node *N = NULL) {
            data = x; next = N;
        }
        node()L next(NULL) {}
        ~node() {}
    };
    node *top_p;
public:
    linStack() { top_p = NULL; }
    ~linStack();
    bool isEmpty() const { return top_p == NULL; }
    void push(const T &x){ top_p = new node(x, top_p); }
    T pop();
    T top() const { return top_p->data; }  
};

template <class T>
linkStack<T>::~linkStack(){
    node* tmp;
    while(top_p ! NULL){
        tmp = top_p;
        top_p = top_p->next;
        delete tmp;
    }
}

template <class T>
T linkStack<T>::pop(){
    node *tmp = top_p;
    T x = tmp->data;
    top_p = top->next;
    delete tmp;
    return x;
}

三、 栈的应用

将递归转成非递归
先来看下常规递归操作

3.1 递归快速排序

3.1.1 python实现

import random
l = list(range(100))
random.shuffle(l)
def quick_sort_simple(lis):
    if len(lis) <= 1:
        return lis
    if  len(lis) == 2:
        return  lis if lis[0] < lis[1] else lis[::-1]
    mid = len(lis) // 2;
    mid_v = lis[mid]
    l = []
    r = []
    for idx, i in enumerate(lis):
        if idx == mid: continue
        if i < mid_v:
            l.append(i)
            continue
        r.append(i)    
    return quick_sort_simple(l) + [mid_v] + quick_sort_simple(r)


class quickSort:    
    def _divide(self, low, high):
        pvt = self.lis[high]
        mid = low-1
        for j in range(low, high):
            if self.lis[j] <= pvt:
                mid+=1;
                self.lis[mid], self.lis[j] = self.lis[j], self.lis[mid]
        
        self.lis[mid+1], self.lis[high] = self.lis[high], self.lis[mid +1]
        return mid + 1
    
    def quick_sort(self, s, e):
        if (s >= e): return
        mid = self._divide(s, e)
        self.quick_sort(s, mid-1)
        self.quick_sort( mid+1, e)

    def __call__(self, lis):
        self.lis = lis
        self.quick_sort(0, len(self.lis)-1)


if __name__ == "__main__":
	l = list(range(100))
	random.shuffle(l)
	print(quick_sort_simple(l))
	
	lis = list(range(100))
	random.shuffle(lis)
	print(lis)
	q = quickSort()
	q(lis)
	print(lis)

3.1.2 cpp实现

#include 
using namespace std;


void show(int lis[], int size);
void swap(int *x, int *y);
void quick_sort(int lis[], int s, int e);
int partition(int array[], int low, int high);


int main(){
    int nums[9] = {1, 10, 3, 6, 7, 9, 10, 23, 5};
    show(nums, 9);
    quick_sort(nums, 0, 8);
    show(nums, 9);
    return 0;
}


void swap(int *x, int *y){
    int tmp;
    tmp = *x;
    *x = *y;
    *y = tmp;
}

int partition(int array[], int low, int high) {
  int pivot = array[high];
  int i = (low - 1);
  // 遍历low->high的每个元素
  for (int j = low; j < high; j++) {
    // 元素小于比较值,将小的值和第i个值交换 (小的元素逐步替换到前面)
    if (array[j] <= pivot) {
      i++;
      swap(&array[i], &array[j]);
    }
  }
  // 最后将 比较的值 替换到 最后个小的值的后面(i+1)
  swap(&array[i + 1], &array[high]);
  return (i + 1); // 返回中间切割点位置
}

void quick_sort(int lis[], int s, int e){
    if( s >= e) return;
    int mid = partition(lis, s, e);
    show(lis, 9);
    quick_sort(lis, s, mid-1);
    quick_sort(lis, mid+1, e);
}


void show(int lis[], int size){
    for(int i=0; i < size; i++){
        cout << lis[i] << " ";
    }
    cout << endl;
}

3.2 非递归快速排序

递归消除方法:

  1. 定义一个存放子问题的栈
  2. 把整个问题放入栈中
  3. While (栈非空)
    • 执行解决问题的过程,分解出的小问题进栈

非递归快速排序伪代码

  • 先将整个数组进栈(这里指的是 数组的头尾)
  • 重复下列工作,直到栈空:
    1. 从栈中弹出一个元素,即一个排序区间。
    2. 将排序区间分成两半。
    3. 检查每一半,如果多于两个元素,则进栈。
#include 
#include 
using namespace std;

void show(int lis[], int size);
void swap(int *x, int *y);
void quick_sort(int lis[], int size);
int partition(int array[], int low, int high);
struct node {
    int left, right;
};

int main(){
    int nums[9] = {1, 10, 3, 6, 7, 9, 10, 23, 5};
    show(nums, 9);
    quick_sort(nums,9);
    show(nums, 9);
    return 0;
}

void swap(int *x, int *y){
    int tmp;
    tmp = *x;
    *x = *y;
    *y = tmp;
}

int partition(int array[], int low, int high) {
  int pivot = array[high];
  int i = (low - 1);
  // 遍历low->high的每个元素
  for (int j = low; j < high; j++) {
    // 元素小于比较值,将小的值和第i个值交换 (小的元素逐步替换到前面)
    if (array[j] <= pivot) {
      i++;
      swap(&array[i], &array[j]);
    }
  }
  // 最后将 比较的值 替换到 最后个小的值的后面(i+1)
  swap(&array[i + 1], &array[high]);
  return (i + 1); // 返回中间切割点位置
}

void quick_sort(int lis[], int size){
    stack<node> st;
    int mid, start, finish;
    node s;
    if(size <= 1) return;
    // 排序
    s.left = 0;
    s.right = size - 1;
    st.push(s);
    while(!st.empty()){
        s = st.top();
        st.pop();
        start = s.left;
        finish = s.right;
        mid = partition(lis, start, finish);
        // quick_sort(lis, s, mid-1);
        if(mid - start > 1){
            s.left = start;
            s.right = mid - 1;
            st.push(s);
        }
        // quick_sort(lis, mid+1, e);
        if(finish - mid > 1){
            s.left = mid + 1;
            s.right = finish;
            st.push(s);
        }
    }
}


void show(int lis[], int size){
    for(int i=0; i < size; i++){
        cout << lis[i] << " ";
    }
    cout << endl;
}

你可能感兴趣的:(数据结构,数据结构,算法,排序算法)