lua各種排序算法

--
--獲取系統時間,計算代碼執行所花費的時間
--以下代碼經過vs2013驗證
--socket.gettime()獲取的正是時間戳,精確度很高,單位是秒。小數點後面還有很多位,可以通過乘以1000這樣的換算,得到微秒(ms)。
--
local socket = require "socket"
local sort = class("sort")

--local start_time = socket.gettime()
--local end_time= socket.gettime()
--local use_time = (end_time - start_time )*1000
--print("start_time: "..start_time .."ms \n")
--print("end_time: "..end_time .."ms \n")
--print("used time: "..use_time .."ms \n")


function sort:init()

    self:init_choose( 7 )

    local yyy = 1
end

function sort:init_choose(iType)
    local cardData = {0x04,0x12,0x07,0x22,0x06,0x43,0x33,0x18,0x09,0x34,0x29}

    local start_time = socket.gettime()
    for i=1, 10000 do       
        cardData = {0x04,0x12,0x07,0x22,0x06,0x43,0x33,0x18,0x09,0x34,0x29}
        if iType == 0 then
            self:test(cardData)              -- 1萬次11個數字累加耗時 0.326s     /  1萬次11個數字空循環耗時 0.1446s    
        elseif iType == 1 then
            self:mao_pao(cardData)           -- 1萬次11個數字冒泡排序耗時 1.66s
        elseif iType == 2 then
            self:xuan_zhe(cardData)          -- 1萬次11個數字選擇排序耗時 1.88s
        elseif iType == 3 then
            self:cha_ru(cardData)            -- 1萬次11個數字插入排序耗時 1.20s
        elseif iType == 4 then
            self:xi_er(cardData)             -- 1萬次11個數字希爾排序耗時 1.92s
        elseif iType == 5 then
            self:gui_bing(cardData)          -- 1萬次11個數字歸併排序耗時 6.095s
        elseif iType == 6 then
            self:quick_sort(cardData, 1, #cardData)     ---- 1萬次11個數字快速排序耗時 2.409s
        elseif iType == 7 then
            self:dui_sort(cardData)          -- 1萬次11個數字堆排序耗時 
        elseif iType == 8 then

        elseif iType == 9 then

        elseif iType == 10 then

        end
    end
    local end_time = socket.gettime()
    local use_time = end_time - start_time

    local xxx = 1
end

--for循環時間開銷
function sort:test( cardData )
    if cardData == nil then return  end
    local cardCount = #cardData
    if cardCount == 0 then return cardData end

    local temp = 0
    for i=1, cardCount do
--        temp = temp + i
    end

    return cardData
end

--冒泡排序
function sort:mao_pao( cardData )
    if cardData == nil then return  end
    local cardCount = #cardData
    if cardCount == 0 then return cardData end

    for i=1, cardCount do
        for j=1, cardCount  - i do
            if cardData[j+1] < cardData[j] then
                local temp = cardData[j+1]
                cardData[j+1] = cardData[j]
                cardData[j] = temp
            end
        end
    end
    return cardData
end

--選擇排序
function sort:xuan_zhe( cardData )
    if cardData == nil then return  end
    local cardCount = #cardData
    if cardCount == 0 then return cardData end

    for i=1, cardCount do
        local minIndex = i
        for j=i, cardCount do
            if cardData[j] < cardData[minIndex] then    --找到最小的數
                minIndex = j        --將最小數的索引保存
            end
        end
        local temp = cardData[minIndex]
        cardData[minIndex] = cardData[i]
        cardData[i] = temp
    end
    return cardData
end

--插入排序
function sort:cha_ru( cardData )
    if cardData == nil then return  end
    local cardCount = #cardData
    if cardCount == 0 then return cardData end

    local current = 1
    for i=1, cardCount-1 do
        current = cardData[i+1]
        local preIndex = i
        while(preIndex >= 1 and current < cardData[preIndex])
        do
            cardData[preIndex+1] = cardData[preIndex]
            preIndex = preIndex - 1
        end
        cardData[preIndex+1] = current
    end
    return cardData
end

--希爾排序
function sort:xi_er( cardData )
    if cardData == nil then return  end
    local cardCount = #cardData
    if cardCount == 0 then return cardData end

    local temp = 1
    local gap = math.floor(cardCount/2)
    while (gap > 0)
    do
        for i = gap, cardCount do
            temp = cardData[i]
            local preIndex = i - gap
            while(preIndex >= 1 and cardData[preIndex] > temp)
            do
                cardData[preIndex + gap] = cardData[preIndex]
                preIndex = preIndex - gap
            end
            cardData[preIndex + gap] = temp
        end
        gap = math.floor(gap/2)
    end
    return cardData
end

--歸併排序
function sort:gui_bing( cardData )
    if cardData == nil then return  end
    local cardCount = #cardData
    if cardCount == 0 then return cardData end

    if cardCount < 2 then return cardData end
    local temp = {}
    self:gui_bing_sort( cardData,1,cardCount, temp )

end
function sort:gui_bing_sort( arr,left,right, temp )
    if left < right then
        local mid = math.floor((left+right)/2)
        self:gui_bing_sort(arr,left,mid,temp)
        self:gui_bing_sort(arr,mid+1,right,temp)
        self:gui_bing_merge(arr, left,mid, right, temp)
    end
end
function sort:gui_bing_merge( arr, left, mid, right, temp )
    local i = left      --左序列指針
    local j = mid + 1   --右序列指針
    local t = 0         --臨時數組指針
    while (i<=mid and j<=right)
    do
        if (arr[i]<=arr[j]) then
            temp[t] = arr[i]
            t = t + 1
            i = i + 1
        else
            temp[t] = arr[j]
            t = t + 1
            j = j + 1
        end
    end

    while (i<=mid)  --將左邊剩餘元素填充進temp中
    do
        temp[t] = arr[i]
        t = t + 1
        i = i + 1
    end

    while (j<=right)    --將右序列剩餘元素填充進temp中
    do
        temp[t] = arr[j]
        t = t + 1
        j = j + 1
    end
    t = 0
    --將temp中的元素全部拷貝到原數組中
    while (left <= right)
    do
        arr[left] = temp[t]
        left = left + 1
        t = t + 1
    end

    return arr
end

--快速排序
function sort:quick_sort( cardData, left, right )
    if left < right then
        local i = left
        local j = right
        local x = cardData[i]
        while (i<j)
        do
            while (i<j and cardData[j]>x)
            do
                j = j - 1       --從右向左找第一個小於x的數
            end
            if i<j then
                cardData[i] = cardData[j]
                i = i + 1
            end
            while (i<j and cardData[i] < x)
            do
                i = i + 1       --從左向右找第一個大於x的數
            end
            if i<j then
                cardData[j] = cardData[i]
                j = j - 1
            end
        end
        cardData[i] = x
        self:quick_sort(cardData, left, i-1)
        self:quick_sort(cardData, i+1, right)
    end
end

--堆排序 (有問題)
function sort:dui_sort( cardData )
    if cardData == nil then return  end
    local cardCount = #cardData
    if cardCount == 0 then return cardData end

    local len = #cardData
    --1.構建要給最大堆
    self:buildMaxHeap(cardData)
    --2.循環將堆首位(最大值)與末位交換,然後再重現調整最大堆
    while ( len > 1 )
    do
        self:dui_sort_swap(cardData, 1, len)
        len = len - 1
        self:dui_sort_adjustHeap(cardData, 1)
    end
    return cardData
end
function sort:buildMaxHeap(array)
    local len = #array
    local temp = math.floor((len-1)/2)
    for i = temp + 1, 1, -1 do
        self:dui_sort_adjustHeap(array, i)
    end
end
function sort:dui_sort_adjustHeap(array, i)
    local maxIndex = i
    local len = #array
    --如果有左子樹,且左子樹大於父節點,則將最大指針指向左子樹
    if (i*2 < len and array[i*2] > array[maxIndex] ) then
        maxIndex = i*2
    end
    --如果有右子樹,且右子樹大於父節點,則將最大指針指向右子樹
    if( i*2+1 < len and array[i*2+1]>array[maxIndex]) then
        maxIndex = i*2 + 1
    end
    --如果父節點不是最大值,則將父節點與最大值交換,並且遞歸調整與父節點交換的位置
    if (maxIndex ~= i) then
        self:dui_sort_swap(array, maxIndex, i)
        self:dui_sort_adjustHeap(array, maxIndex)
    end
end
function sort:dui_sort_swap(arr, a, b)
    local temp = arr[a]
    arr[a] = arr[b]
    arr[b] = temp
end

--計數排序
function sort:counting( cardData )
    if cardData == nil then return  end
    local cardCount = #cardData
    if cardCount == 0 then return cardData end


end

return sort

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