?? 排序Book

[toc]

[圖片上傳失敗...(image-cf319d-1646826776257)]

時(shí)間復(fù)雜度 O(n^2) 級(jí)排序算法

冒泡排序

冒泡排序是入門(mén)級(jí)的算法帽芽,但也有一些有趣的玩法杈女。通常來(lái)說(shuō)际跪,冒泡排序有三種寫(xiě)法:

  • 一邊比較一邊向后兩兩交換屿衅,將最大值 / 最小值冒泡到最后一位等缀;
  • 經(jīng)過(guò)優(yōu)化的寫(xiě)法:使用一個(gè)變量記錄當(dāng)前輪次的比較是否發(fā)生過(guò)交換匆帚,如果沒(méi)有發(fā)生交換表示已經(jīng)有序能曾,不再繼續(xù)排序宵溅;
  • 進(jìn)一步優(yōu)化的寫(xiě)法:除了使用變量記錄當(dāng)前輪次是否發(fā)生交換外凌简,再使用一個(gè)變量記錄上次發(fā)生交換的位置,下一輪排序時(shí)到達(dá)上次交換的位置就停止比較恃逻。
冒泡排序(一)
public static void bubbleSort(int[] arr) {
    for (int i = 0; i < arr.length - 1; i++) {
        for (int j = 0; j < arr.length - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                // 如果左邊的數(shù)大于右邊的數(shù)雏搂,則交換,保證右邊的數(shù)字最大
                swap(arr, j, j + 1);
            }
        }
    }
}
冒泡排序(二)
public static void bubbleSort(int[] arr) {
    // 初始時(shí) swapped 為 true寇损,否則排序過(guò)程無(wú)法啟動(dòng)
    boolean swapped = true;
    for (int i = 0; i < arr.length - 1; i++) {
        // 如果沒(méi)有發(fā)生過(guò)交換凸郑,說(shuō)明剩余部分已經(jīng)有序,排序完成
        if (!swapped) break;
        // 設(shè)置 swapped 為 false矛市,如果發(fā)生交換芙沥,則將其置為 true
        swapped = false;
        for (int j = 0; j < arr.length - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                // 如果左邊的數(shù)大于右邊的數(shù),則交換浊吏,保證右邊的數(shù)字最大
                swap(arr, j, j + 1);
                // 表示發(fā)生了交換
                swapped = true;
            }
        }
    }
}

最外層的 for 循環(huán)每經(jīng)過(guò)一輪而昨,剩余數(shù)字中的最大值仍然是被移動(dòng)到當(dāng)前輪次的最后一位。這種寫(xiě)法相對(duì)于第一種寫(xiě)法的優(yōu)點(diǎn)是:如果一輪比較中沒(méi)有發(fā)生過(guò)交換找田,則立即停止排序歌憨,因?yàn)榇藭r(shí)剩余數(shù)字一定已經(jīng)有序了。
[圖片上傳失敗...(image-482b13-1646826776257)]

冒泡排序(三種)
public static void bubbleSort(int[] arr) {
    boolean swapped = true;
    // 最后一個(gè)沒(méi)有經(jīng)過(guò)排序的元素的下標(biāo)
    int indexOfLastUnsortedElement = arr.length - 1;
    // 上次發(fā)生交換的位置
    int swappedIndex = -1;
    while (swapped) {
        swapped = false;
        for (int i = 0; i < indexOfLastUnsortedElement; i++) {
            if (arr[i] > arr[i + 1]) {
                // 如果左邊的數(shù)大于右邊的數(shù)墩衙,則交換务嫡,保證右邊的數(shù)字最大
                swap(arr, i, i + 1);
                // 表示發(fā)生了交換
                swapped = true;
                // 更新交換的位置
                swappedIndex = i;
            }
        }
        // 最后一個(gè)沒(méi)有經(jīng)過(guò)排序的元素的下標(biāo)就是最后一次發(fā)生交換的位置
        indexOfLastUnsortedElement = swappedIndex;
    }
}

經(jīng)過(guò)再一次的優(yōu)化甲抖,代碼看起來(lái)就稍微有點(diǎn)復(fù)雜了。最外層的 while 循環(huán)每經(jīng)過(guò)一輪心铃,剩余數(shù)字中的最大值仍然是被移動(dòng)到當(dāng)前輪次的最后一位准谚。

在下一輪比較時(shí),只需比較到上一輪比較中去扣,最后一次發(fā)生交換的位置即可柱衔。因?yàn)楹竺娴乃性囟紱](méi)有發(fā)生過(guò)交換,必然已經(jīng)有序了厅篓。

當(dāng)一輪比較中從頭到尾都沒(méi)有發(fā)生過(guò)交換秀存,則表示整個(gè)列表已經(jīng)有序,排序完成羽氮。

選擇排序

選擇排序的思想是:雙重循環(huán)遍歷數(shù)組,每經(jīng)過(guò)一輪比較惫恼,找到最小元素的下標(biāo)档押,將其交換至首位。

最小選擇排序
public static void selectionSort(int[] arr) {
    int minIndex;
    for (int i = 0; i < arr.length - 1; i++) {
        minIndex = i;
        for (int j = i + 1; j < arr.length; j++) {
            if (arr[minIndex] > arr[j]) {
                // 記錄最小值的下標(biāo)
                minIndex = j;
            }
        }
        // 將最小元素交換至首位
        swap(arr, i , minIndex);
    }
}
二元選擇排序

每輪選擇時(shí)記錄最小值和最大值祈纯,可以把數(shù)組需要遍歷的范圍縮小一倍令宿。

public static void selectionSort2(int[] arr) {
    int minIndex, maxIndex;
    // i 只需要遍歷一半
    for (int i = 0; i < arr.length / 2; i++) {
        minIndex = i;
        maxIndex = i;
        for (int j = i + 1; j < arr.length - i; j++) {
            if (arr[minIndex] > arr[j]) {
                // 記錄最小值的下標(biāo)
                minIndex = j;
            }
            if (arr[maxIndex] < arr[j]) {
                // 記錄最大值的下標(biāo)
                maxIndex = j;
            }
        }
        // 如果 minIndex 和 maxIndex 都相等,那么他們必定都等于 i腕窥,且后面的所有數(shù)字都與 arr[i] 相等粒没,此時(shí)已經(jīng)排序完成
        if (minIndex == maxIndex) break;
        
        // 將最小元素交換至首位
        swap(arr, i , minIndex);
        
        // 如果最大值的下標(biāo)剛好是 i,由于 arr[i] 和 arr[minIndex] 已經(jīng)交換了簇爆,所以這里要更新 maxIndex 的值癞松。
        if (maxIndex == i) maxIndex = minIndex;
        
        // 將最大元素交換至末尾
        int lastIndex = arr.length - 1 - i;
        swap(arr, lastIndex , maxIndex);
    }
}

冒泡排序和選擇排序異同?

相同點(diǎn):

都是兩層循環(huán)入蛆,時(shí)間復(fù)雜度都為 O(n2)
都只使用有限個(gè)變量响蓉,空間復(fù)雜度O(1)。

不同點(diǎn):

冒泡排序在比較過(guò)程中就不斷交換哨毁;而選擇排序增加了一個(gè)變量保存最小值 / 最大值的下標(biāo)枫甲,遍歷完成后才交換,減少了交換次數(shù)扼褪。
事實(shí)上想幻,冒泡排序和選擇排序還有一個(gè)非常重要的不同點(diǎn),那就是:

冒泡排序法是穩(wěn)定的话浇,選擇排序法是不穩(wěn)定的脏毯。
想要理解這點(diǎn)不同,我們先要知道什么是排序算法的穩(wěn)定性凳枝。

插入排序

插入排序的思想非常簡(jiǎn)單抄沮,生活中有一個(gè)很常見(jiàn)的場(chǎng)景:在打撲克牌時(shí)跋核,我們一邊抓牌一邊給撲克牌排序,每次摸一張牌叛买,就將它插入手上已有的牌中合適的位置,逐漸完成整個(gè)排序率挣。

插入排序有兩種寫(xiě)法:

  • 交換法:在新數(shù)字插入過(guò)程中刻伊,不斷與前面的數(shù)字交換,直到找到自己合適的位置椒功。
  • 移動(dòng)法:在新數(shù)字插入過(guò)程中捶箱,與前面的數(shù)字不斷比較,前面的數(shù)字不斷向后挪出位置动漾,當(dāng)新數(shù)字找到自己的位置后丁屎,插入一次即可。
交換法
public static void insertSort(int[] arr) {
    // 從第二個(gè)數(shù)開(kāi)始旱眯,往前插入數(shù)字
    for (int i = 1; i < arr.length; i++) {
        // j 記錄當(dāng)前數(shù)字下標(biāo)
        int j = i;
        // 當(dāng)前數(shù)字比前一個(gè)數(shù)字小晨川,則將當(dāng)前數(shù)字與前一個(gè)數(shù)字交換
        while (j >= 1 && arr[j] < arr[j - 1]) {
            swap(arr, j, j - 1);
            // 更新當(dāng)前數(shù)字下標(biāo)
            j--;
        }
    }
}

當(dāng)數(shù)字少于兩個(gè)時(shí),不存在排序問(wèn)題删豺,當(dāng)然也不需要插入共虑,所以我們直接從第二個(gè)數(shù)字開(kāi)始往前插入。

整個(gè)過(guò)程就像是已經(jīng)有一些數(shù)字坐成了一排呀页,這時(shí)一個(gè)新的數(shù)字要加入妈拌,這個(gè)新加入的數(shù)字原本坐在這一排數(shù)字的最后一位,然后它不斷地與前面的數(shù)字比較蓬蝶,如果前面的數(shù)字比它大尘分,它就和前面的數(shù)字交換位置。

移動(dòng)法

我們發(fā)現(xiàn)疾党,在交換法插入排序中音诫,每次交換數(shù)字時(shí),swap 函數(shù)都會(huì)進(jìn)行三次賦值操作雪位。但實(shí)際上竭钝,新插入的這個(gè)數(shù)字并不一定適合與它交換的數(shù)字所在的位置。也就是說(shuō)雹洗,它剛換到新的位置上不久香罐,下一次比較后,如果又需要交換时肿,它馬上又會(huì)被換到前一個(gè)數(shù)字的位置庇茫。

由此,我們可以想到一種優(yōu)化方案:讓新插入的數(shù)字先進(jìn)行比較螃成,前面比它大的數(shù)字不斷向后移動(dòng)旦签,直到找到適合這個(gè)新數(shù)字的位置后查坪,新數(shù)字只做一次插入操作即可。

這種方案我們需要把新插入的數(shù)字暫存起來(lái)宁炫,代碼如下:

public static void insertSort(int[] arr) {
    // 從第二個(gè)數(shù)開(kāi)始偿曙,往前插入數(shù)字
    for (int i = 1; i < arr.length; i++) {
        int currentNumber = arr[i];
        int j = i - 1;
        // 尋找插入位置的過(guò)程中,不斷地將比 currentNumber 大的數(shù)字向后挪
        while (j >= 0 && currentNumber < arr[j]) {
            arr[j + 1] = arr[j];
            j--;
        }
        // 兩種情況會(huì)跳出循環(huán):1. 遇到一個(gè)小于或等于 currentNumber 的數(shù)字羔巢,跳出循環(huán)望忆,currentNumber 就坐到它后面。
        // 2. 已經(jīng)走到數(shù)列頭部竿秆,仍然沒(méi)有遇到小于或等于 currentNumber 的數(shù)字启摄,也會(huì)跳出循環(huán),此時(shí) j 等于 -1幽钢,currentNumber 就坐到數(shù)列頭部歉备。
        arr[j + 1] = currentNumber;
    }
}

整個(gè)過(guò)程就像是已經(jīng)有一些數(shù)字坐成了一排,這時(shí)一個(gè)新的數(shù)字要加入匪燕,所以這一排數(shù)字不斷地向后騰出位置威创,當(dāng)新的數(shù)字找到自己合適的位置后,就可以直接坐下了谎懦。重復(fù)此過(guò)程,直到排序結(jié)束溃斋。

時(shí)間復(fù)雜度 O(nlogn) 級(jí)排序算法

??希爾排序

處理完一組間隔序列后界拦,再回來(lái)處理下一組間隔序列。

public static void shellSort(int[] arr) {
    // 間隔序列梗劫,在希爾排序中我們稱之為增量序列
    for (int gap = arr.length / 2; gap > 0; gap /= 2) {
        // 從 gap 開(kāi)始享甸,按照順序?qū)⒚總€(gè)元素依次向前插入自己所在的組
        for (int i = gap; i < arr.length; i++) {
            // currentNumber 站起來(lái),開(kāi)始找位置
            int currentNumber = arr[i];
            // 該組前一個(gè)數(shù)字的索引
            int preIndex = i - gap;
            while (preIndex >= 0 && currentNumber < arr[preIndex]) {
                // 向后挪位置
                arr[preIndex + gap] = arr[preIndex];
                preIndex -= gap;
            }
            // currentNumber 找到了自己的位置梳侨,坐下
            arr[preIndex + gap] = currentNumber;
        }
    }
}

??堆排序

?????

  • 對(duì)于完全二叉樹(shù)中的第 i 個(gè)數(shù)蛉威,它的左子節(jié)點(diǎn)下標(biāo):left = 2i + 1
  • 對(duì)于完全二叉樹(shù)中的第 i 個(gè)數(shù),它的右子節(jié)點(diǎn)下標(biāo):right = left + 1
  • 對(duì)于有 n 個(gè)元素的完全二叉樹(shù)(n≥2)走哺,它的最后一個(gè)非葉子結(jié)點(diǎn)的下標(biāo) n/2 - 1
  1. 構(gòu)建大頂堆buildMaxHeap蚯嫌,將數(shù)組視作一顆完全二叉樹(shù),從它的最后一個(gè)非葉子結(jié)點(diǎn)開(kāi)始丙躏,調(diào)整此結(jié)點(diǎn)和其左右子樹(shù)择示,使這三個(gè)數(shù)字構(gòu)成一個(gè)大頂堆
  • 當(dāng)構(gòu)建出大頂堆之后,就要把冠軍交換到數(shù)列最后晒旅,深藏功與名栅盲。來(lái)到冠軍寶座的新人又要和李小胖一樣,開(kāi)始向下比較废恋,找到自己的真實(shí)位置谈秫,使得剩下的n?1 個(gè)數(shù)字構(gòu)建成新的大頂堆扒寄。這就是 heapSort 方法的 for 循環(huán)中,調(diào)用 maxHeapify 的原因拟烫。
  • 變量 heapSize 用來(lái)記錄還剩下多少個(gè)數(shù)字沒(méi)有排序完成该编,每當(dāng)交換了一個(gè)堆頂?shù)臄?shù)字,heapSize 就會(huì)減构灸。在 maxHeapify 方法中上渴,使用 heapSize 來(lái)限制剩下的選手,不要和已經(jīng)躺在數(shù)組最后喜颁,當(dāng)過(guò)冠軍的人比較稠氮,免得被暴揍。
  1. maxHeapify調(diào)整大頂堆
public static void heapSort(int[] arr) {
    // 構(gòu)建初始大頂堆
    buildMaxHeap(arr);
    for (int i = arr.length - 1; i > 0; i--) {
        // 將最大值交換到數(shù)組最后
        swap(arr, 0, i);
        // 調(diào)整剩余數(shù)組半开,使其滿足大頂堆
        maxHeapify(arr, 0, i);
    }
}
// 構(gòu)建初始大頂堆
private static void buildMaxHeap(int[] arr) {
    // 從最后一個(gè)非葉子結(jié)點(diǎn)開(kāi)始調(diào)整大頂堆隔披,最后一個(gè)非葉子結(jié)點(diǎn)的下標(biāo)就是 arr.length / 2-1
    for (int i = arr.length / 2 - 1; i >= 0; i--) {
        maxHeapify(arr, i, arr.length);
    }
}
// 調(diào)整大頂堆,第三個(gè)參數(shù)表示剩余未排序的數(shù)字的數(shù)量寂拆,也就是剩余堆的大小
private static void maxHeapify(int[] arr, int i, int heapSize) {
    // 左子結(jié)點(diǎn)下標(biāo)
    int l = 2 * i + 1;
    // 右子結(jié)點(diǎn)下標(biāo)
    int r = l + 1;
    // 根結(jié)點(diǎn)奢米、左子樹(shù)結(jié)點(diǎn)、右子樹(shù)結(jié)點(diǎn)三者中的最大值下標(biāo)
    int largest = getMaxIndex(arr, i, l, r, heapSize);

    if (largest != i) {
        // 將最大值交換為根結(jié)點(diǎn)
        swap(arr, i, largest);
        // 再次調(diào)整交換數(shù)字后的大頂堆
        maxHeapify(arr, largest, heapSize);
    }
}
// 獲得i,l,r最大值下標(biāo)
public static int getMaxIndex(int[] arr, int i, int l, int r, int heapSize) {
    // 記錄根結(jié)點(diǎn)纠永、左子樹(shù)結(jié)點(diǎn)鬓长、右子樹(shù)結(jié)點(diǎn)三者中的最大值下標(biāo)
    int largest = i;
    // 與左子樹(shù)結(jié)點(diǎn)比較
    if (l < heapSize && arr[l] > arr[largest]) {
        largest = l;
    }
    // 與右子樹(shù)結(jié)點(diǎn)比較
    if (r < heapSize && arr[r] > arr[largest]) {
        largest = r;
    }
    return largest;
}

????快速排序

取基數(shù),左邊比基數(shù)小尝江,右邊比基數(shù)大涉波。
遞歸quickSort排序,區(qū)域內(nèi)的數(shù)字少于 2 個(gè)炭序,退出遞歸啤覆。
partition分區(qū),雙指針交換左右數(shù)字

  • 注意退出while判斷l(xiāng)eft < right,
  • 如果 left 和 right 相等惭聂,單獨(dú)比較 arr[right] 和 pivot
  • 將基數(shù)和軸交換
public static void quickSort(int[] arr) {
    quickSort(arr, 0, arr.length - 1);
}
public static void quickSort(int[] arr, int start, int end) {
    // 如果區(qū)域內(nèi)的數(shù)字少于 2 個(gè)窗声,退出遞歸
    if (start >= end) return;
    // 將數(shù)組分區(qū),并獲得中間值的下標(biāo)
    int middle = partition(arr, start, end);
    // 對(duì)左邊區(qū)域快速排序
    quickSort(arr, start, middle - 1);
    // 對(duì)右邊區(qū)域快速排序
    quickSort(arr, middle + 1, end);
}
// 將 arr 從 start 到 end 分區(qū)辜纲,左邊區(qū)域比基數(shù)小笨觅,右邊區(qū)域比基數(shù)大,然后返回中間值的下標(biāo)
public static int partition(int[] arr, int start, int end) {
    // 取第一個(gè)數(shù)為基數(shù)
    int pivot = arr[start];
    // 從第二個(gè)數(shù)開(kāi)始分區(qū)
    int left = start + 1;
    // 右邊界
    int right = end;
    while (left < right) {
        // 找到第一個(gè)大于基數(shù)的位置
        while (left < right && arr[left] <= pivot) left++;
        // 找到第一個(gè)小于基數(shù)的位置
        while (left < right && arr[right] >= pivot) right--;
        // 交換這兩個(gè)數(shù)侨歉,使得左邊分區(qū)都小于或等于基數(shù)屋摇,右邊分區(qū)大于或等于基數(shù)
        if (left < right) {
            swap(arr, left, right);
            left++;
            right--;
        }
    }
    // 如果 left 和 right 相等,單獨(dú)比較 arr[right] 和 pivot
    if (left == right && arr[right] > pivot) right--;
    // 此時(shí)right指向了left的最后一位幽邓,將基數(shù)和軸交換
    swap(arr, start, right);
    return right;
}

??歸并排序

將 1 個(gè)數(shù)字組成的有序數(shù)組合并成一個(gè)包含 2 個(gè)數(shù)字的有序數(shù)組炮温,再將 2 個(gè)數(shù)字組成的有序數(shù)組合并成包含 4 個(gè)數(shù)字的有序數(shù)組...直到整個(gè)數(shù)組排序完成

額外空間歸并
public static void mergeSort(int[] arr) {
    if (arr.length == 0) return;
    int[] result = new int[arr.length];
    mergeSort(arr, 0, arr.length - 1, result);
}

// 對(duì) arr 的 [start, end] 區(qū)間歸并排序
private static void mergeSort(int[] arr, int start, int end, int[] result) {
    // 只剩下一個(gè)數(shù)字,停止拆分
    if (start == end) return;
    int middle = (start + end) / 2;
    // 拆分左邊區(qū)域牵舵,并將歸并排序的結(jié)果保存到 result 的 [start, middle] 區(qū)間
    mergeSort(arr, start, middle, result);
    // 拆分右邊區(qū)域柒啤,并將歸并排序的結(jié)果保存到 result 的 [middle + 1, end] 區(qū)間
    mergeSort(arr, middle + 1, end, result);
    // 合并左右區(qū)域到 result 的 [start, end] 區(qū)間
    merge(arr, start, end, result);
}

// 將 result 的 [start, middle] 和 [middle + 1, end] 區(qū)間合并
private static void merge(int[] arr, int start, int end, int[] result) {
    int end1 = (start + end) / 2;
    int start2 = end1 + 1;
    // 用來(lái)遍歷數(shù)組的指針
    int index1 = start;
    int index2 = start2;
    while (index1 <= end1 && index2 <= end) {
        if (arr[index1] <= arr[index2]) {
            result[index1 + index2 - start2] = arr[index1++];
        } else {
            result[index1 + index2 - start2] = arr[index2++];
        }
    }
    // 將剩余數(shù)字補(bǔ)到結(jié)果數(shù)組之后
    while (index1 <= end1) {
        result[index1 + index2 - start2] = arr[index1++];
    }
    while (index2 <= end) {
        result[index1 + index2 - start2] = arr[index2++];
    }
    // 將 result 操作區(qū)間的數(shù)字拷貝到 arr 數(shù)組中倦挂,以便下次比較
    while (start <= end) {
        arr[start] = result[start++];
    }
}

時(shí)間復(fù)雜度 O(n) 級(jí)排序算法

計(jì)數(shù)排序

基數(shù)排序

桶排序

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市担巩,隨后出現(xiàn)的幾起案子方援,更是在濱河造成了極大的恐慌,老刑警劉巖涛癌,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件犯戏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡拳话,警方通過(guò)查閱死者的電腦和手機(jī)先匪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)弃衍,“玉大人呀非,你說(shuō)我怎么就攤上這事【刀ⅲ” “怎么了岸裙?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)速缆。 經(jīng)常有香客問(wèn)我降允,道長(zhǎng),這世上最難降的妖魔是什么艺糜? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任拟糕,我火速辦了婚禮,結(jié)果婚禮上倦踢,老公的妹妹穿的比我還像新娘。我一直安慰自己侠草,他們只是感情好辱挥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著边涕,像睡著了一般晤碘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上功蜓,一...
    開(kāi)封第一講書(shū)人閱讀 51,604評(píng)論 1 305
  • 那天园爷,我揣著相機(jī)與錄音,去河邊找鬼式撼。 笑死童社,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的著隆。 我是一名探鬼主播扰楼,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼呀癣,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了弦赖?” 一聲冷哼從身側(cè)響起项栏,我...
    開(kāi)封第一講書(shū)人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蹬竖,沒(méi)想到半個(gè)月后沼沈,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡币厕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年列另,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劈榨。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡访递,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出同辣,到底是詐尸還是另有隱情拷姿,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布旱函,位于F島的核電站响巢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏棒妨。R本人自食惡果不足惜踪古,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望券腔。 院中可真熱鬧伏穆,春花似錦、人聲如沸纷纫。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)辱魁。三九已至烟瞧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間染簇,已是汗流浹背参滴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锻弓,地道東北人砾赔。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親过蹂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子十绑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容