[數據結構]棧的插入,歸併以及快速排序

棧的排序算法:


第一種,類似於插入排序,(允許額外利用一個棧),每一步的循環不變式是temp中的元素是有序的。直接上代碼:


void sortStack(stack& s)
{
    if(s.empty()) return;
    stack temp; //輔助棧

    while(!s.empty())
    {
        int cur = s.top();
        s.pop();
	
	    //每一次將s的棧頂的元素取出,插入到temp的合適的位置上,插入位置之上的元素彈回s。
        if(temp.empty())
        {
            temp.push(cur);
            continue;
        }
        while(!temp.empty())
        {
            if(temp.top() < cur) 
            {
                s.push(temp.top());
                temp.pop();
            }
            else
            {
                temp.push(cur);   
                break;
            }
        }
        if(temp.empty()) temp.push(cur); //如果將temp站內的元素全部彈完了,那麼將當前元素放在棧底
    }
    s.swap(temp); //交換兩者
}

第二種排序:快速排序,快速排序每次根據一個partition將棧分爲兩個部分,於是下面的代碼中使用了兩個棧來作爲輔助棧。


void quickSortStack(stack &s)
{
    if(s.empty()) return;
    
    int pivot = s.top();s.pop(); //直接取棧頂元素作爲pivot
    
    if(s.empty())  //如果當前只有一個元素。那麼直接返回,不用再排序了
    {
        s.push(pivot);
        return;
    }
    
    stack less, grt; //記錄比當前元素大的和小的的數字的棧
    
    while(!s.empty())
    {
        int cur = s.top();s.pop();
        if(cur <= pivot)
        {
            less.push(cur);
        }
        else
        {
            grt.push(cur);
        }
    }
    if(less.empty()) less.push(pivot);
    else grt.push(pivot);
    
    //遞歸調用
    quickSortStack(less);
    quickSortStack(grt);
    
    //將調用的結果Merge到s中歐,先將grt的部分壓入棧底。再壓入less的部分,
    //此處爲了減少入棧與出棧的次數,直接使用less來作爲中轉
    
    while(!grt.empty())
    {
        s.push(grt.top());
        grt.pop();
    }

    while(!s.empty())
    {
        less.push(s.top());
        s.pop();
    }
    
    s.swap(less);
}

第三種排序:歸併排序。直接上代碼,比較簡單:

void merge(stack &s, stack &left, stack &right)
{
    assert(s.empty());
    if(left.empty() && right.empty())
    {
        return ;
    }
    if(left.empty())
    {
        s.swap(right);
        return;
    }
    if(right.empty())
    {
        s.swap(left);
        return;
    }


    int l = left.top(); left.pop();
    int r = right.top(); right.pop();
    
    while(1)
    {
        if(l < r)
        {
            s.push(r);
            if(right.empty())
            {
                s.push(l);
                break;
            }
            r = right.top();right.pop();
        }
        else
        {
            s.push(l);
            if(left.empty())
            {
                s.push(r);
                break;
            }
            l = left.top(); left.pop();
        } 

    }
    while(!left.empty())
    {
        l = left.top(); left.pop();
        s.push(l);
    }
    while(!right.empty())
    {
        r = right.top(); right.pop();
        s.push(r);
    }
    while(!s.empty()) {
        right.push(s.top()); s.pop();
    }
    right.swap(s);
}  


void mergeSortStack(stack &s)
{
    //empty
    if(s.empty()) return;
    
    //single element
    //maybe a little weird
    int temp = s.top(); s.pop();
    
    if(s.empty()) {
        s.push(temp);
        return;
    }
    s.push(temp);

    stack left, right;
    while(!s.empty())
    {
        int cur = s.top();s.pop();
        left.push(cur);
        if(s.empty()) break;
        cur = s.top(); s.pop();
        right.push(cur);
    }
    mergeSortStack(left);
    mergeSortStack(right);
    merge(s,left,right);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章