js 二叉樹

百度搜索 二叉樹
頭兩個鏈接就是這倆

JavaScript二叉樹深入理解

javascript實現(xiàn)數(shù)據(jù)結(jié)構(gòu): 樹和二叉樹,二叉樹的遍歷和基本操作

第二個博客的內(nèi)容應(yīng)該算第一個博客的基礎(chǔ)知識.
第一個比較好懂,第二個比較難,代碼量也多.

function Node (data,left,right) {
        this.data = data;
        this.left = left;
        this.right = right;
      }
      function BST () {
        this.root = null;
        this.insert = insert;
        this.find = find;
        this.remove = remove;
      }
      
      function insert (data) {
        var node = new Node(data,null,null);
        if(this.root == null) {
          this.root = node;
        } else {
          var current = this.root;
          while(true) {
            if(current.data > data) {
              if(current.left === null) {
                current.left = node;
                break;
              }
              current = current.left;
            }else {
              if(current.right === null) {
                current.right = node;
                break;
              }
              current = current.right;
            }
          }
        }
      }
      
      
      //二叉樹查節(jié)點
      function find (data) {
        var current = this.root;
        while (true){
            if(data == current.data) {
              return current;
            }
            current = data < current.data ? current.left : current.right;
            if(current === null) {
              return null;
            }
        }
      }
      
      //二叉樹刪除節(jié)點(只刪除葉子節(jié)點, 只有一個子節(jié)點的Node)
      
      function remove (data) {
        this.root = removeNode(this.root,data);
      }
      
      function removeNode (node, data) {
        if(node === null) {
          return null;
        }
        
        if(data === node.data) {
          if(node.left == null && node.right == null) {
            return null;
          }
          if(node.left === null) {
            return node.right;
          }
          if(node.right === null) {
            return node.left;
          }
          //這里有疑問, 如果node.left !== null && node.right !== right 這種情況怎么處理?
          //怪不得 上面說,只刪除只有一個子節(jié)點的Node
          //邏輯上來講, 可以把左子樹 return 給 右子樹, 
          //右子樹 return 給 刪除節(jié)點的 parent 是不是就可以保持結(jié)構(gòu)了? 
        }else if (data < node.data) {
          node.left = removeNode(node.left,data);
          return node;
        }else {
          node.right = removeNode(node.right,data);
          return node;
        }
      }
      抄寫第二遍時,感覺 remove() removeNode() 這個遞歸用得實在是太巧妙了, 
      當(dāng)初第一人到底是怎么想到這個結(jié)構(gòu)的?

      第一個感覺是,每次遞歸的執(zhí)行,不依賴遞歸返回的值?
      第二個感覺是,遞歸的過程當(dāng)中,他的返回值很自然的又形成了一個對象,
      一個二叉樹.怎么去的就怎么返回?

      也許我應(yīng)該問, 如果 remove 和 removeNode 非要寫在一個函數(shù),是不是會變得很復(fù)雜?
      他是怎么想到要分離開的?

      或者我應(yīng)該問,寫這個的核心邏輯出發(fā)點在哪里?
      需求是: 刪除節(jié)點,返回子節(jié)點,沒有就返回自身?
      因為我沒看懂,所以是我想復(fù)雜了嗎?
      


      var bst = new BST();
      bst.insert(5);
      bst.insert(8);
      bst.insert(9);
      bst.insert(1);
      bst.insert(3);
      console.log(bst);
      // 這個二叉樹,根節(jié)點取決于,頭一個放誰進(jìn)去.
      // 同樣的一組數(shù)據(jù),根據(jù)根節(jié)點放誰, 二叉樹的結(jié)構(gòu)也可能不同

在抄第二篇博客之前,發(fā)現(xiàn),
第二篇博客和第一篇博客的內(nèi)容完全不一樣,
應(yīng)該是第一篇的基礎(chǔ)內(nèi)容,

    樹狀結(jié)構(gòu)可以有很多種, 二叉樹是其中一種.

    二叉樹結(jié)構(gòu)的數(shù)據(jù)存儲有三種

  1.一種是數(shù)組.數(shù)組當(dāng)中的順序,反映二叉樹中的位置.
      具體這個順序和位置的關(guān)系,看博客,我也不是很清楚.
      (這個叫順序存儲結(jié)構(gòu))

  2.一種是二叉鏈表,
      每個節(jié)點有三個存儲結(jié)構(gòu)? 一個放left,一個放data,一個放right
      沒錯博客一,實際上就是二叉鏈表的形式.
      (這個叫鏈?zhǔn)酱鎯Y(jié)構(gòu))          

  3.一種是三叉鏈表,
      在left,data,right,之外放一個parent,用來指向parent.

下面是第二個博客的完整版代碼.

(function () {
        // 順序存儲結(jié)構(gòu)的遍歷
        var tree = [1,2,3,4,5,,6,,,7];
        // 先序遍歷
        console.log('preOrder');
        void function preOrderTraverse (x, visit) {
            visit(tree[x]);
            tree[2 * x + 1] && preOrderTraverse(2 * x + 1,visit);
            tree[2 * x + 2] && preOrderTraverse(2 * x + 2,visit);
        }(0, function (value) {
            console.log(value);
        })
         
         //中序遍歷
         console.log('inOrder:');
         void function inOrderTraverse (x, visit) {
          tree[2 * x + 1] && inOrderTraverse(2 * x + 1,visit);
          visit(tree[x]);
          tree[2 * x + 2] && inOrderTraverse(2 * x + 2,visit);
         }(0, function (value) {
          console.log(value);
        })
         
         console.log('postOrder:');
         void function postOrderTraverse (x, visit) {
          tree[2 * x + 1] && postOrderTraverse(2 * x + 1,visit);
          tree[2 * x + 2] && postOrderTraverse(2 * x + 2,visit);
          visit(tree[x]);
         }(0, function (value) {
          console.log(value);
        })
      })()
      
      
      var Stack = require('../Stack/stack');// 這就很尷尬了, 我不知道具體 Stack,Queue 怎么寫的
      var Queue = require('../Queue/Queue').Queue;
      
      
      function BinaryTree (data, leftChild, rightChild) {
        this.data = data || null;
        // 左右孩子節(jié)點
        this.leftChild = leftChild || null;
        this.rihgtChild  rightChild || null;
      }
      
      exports.BinaryTree = BinaryTree;// 這是為了導(dǎo)出?
      
      BinaryTree.prototype = {// 這個跟 博客一上的區(qū)別是,把函數(shù)定義在原型鏈上, 調(diào)用方式是一樣的.
        constructor : BinaryTree,
        // 判斷兩棵樹是否相似
        
        isSimilar : function (tree) {// tree 是另一個節(jié)點數(shù),也就是一個二叉樹對象.假定是跟 this相同的結(jié)構(gòu)就好理解
            return tree && 
               this.leftChild && isSimilar.call(this.leftChild,tree.leftChild) && this.rightChild &&
               isSimilar.call(this.rightChild,tree.rightChild);
               // 真是各種遞歸用得太巧妙了. 
               // 想到一個題目, 如何比較兩個 地址不同的 對象的內(nèi)容是否相同? 回頭想一下,
        },
        
        // 把一個數(shù)組,變成二叉樹鏈?zhǔn)酱鎯Y(jié)構(gòu)
        createBinaryTree: function (tree) {// 在一個函數(shù)里面遞歸另一個函數(shù)? 真是各種秀
          // 這尼瑪,這個tree 很明顯跟上面那個 tree 的數(shù)據(jù)類型應(yīng)該不一樣, 這個應(yīng)該是個 數(shù)組,順序存儲結(jié)構(gòu).
            void function preOrderTraverse (node, x, vist) {
                visit (node,tree[x]);
                tree[2 * x + 1] && preOrderTraverse(node.leftChild = new BinaryTree(), 2 * x + 1,visit);
                tree[2 * x + 2] && preOrderTraverse(node.rightChild = new BinaryTree(), 2 * x + 2,visit); 
            }(this,0,function (node,value) {
                node.data = value;
            })
        },
        //上面這段代碼,能讀懂, 但一時很難熟悉這種結(jié)構(gòu), 練習(xí)到后面,真的有可能隨手就能寫出這種結(jié)構(gòu)?
        
        //先序遍歷二叉樹的非遞歸算法
        
        preOrder_stack: function  (visit) {// 所以我們可以把visit 看成是一個回調(diào)函數(shù).
            var stack = new Stack();// 這就懵逼了,他沒具體寫 Stack
            //https://www.npmjs.com/package/stackjs 網(wǎng)上說這是個第三方 js
            stack.push(this);
            
            while (stack.top) {// stack.js 沒有top 屬性或方法啊
              var p;
              // 向左走到盡頭
              while ((p = stack.peek())){// stack.peek() 返回的應(yīng)該是 stack 中 最后一個push進(jìn)來的元素.
                p.data && visit(p.data);// 放進(jìn)一個stack,遍歷一個,
                stack.push(p.leftChild);
              }
              
              stack.pop();// 把上面循環(huán)之后的 最后一個 leftChild 清空.
              
              if (stack.top) {// top 依然不知道是什么東西 應(yīng)該是指 跟節(jié)點, 或者頭一個 push 進(jìn)去的節(jié)點.
                p = stack.pop();// 把 最后倒數(shù)第二個 leftChild刪除的同時拿出來, 因為一定會有 rightChild
                stack.push(p.rightChild);// 把rightChild拿出來.放進(jìn)stack里.
                //這個循環(huán)的出口在哪里? 出口就是, stack.pop() 把this也給 刪除的時候, stack.pop 就會false;
              }
            }
        },
        // 勉強(qiáng)看懂了, 真是天秀. 程序員世界里,沒有最裝逼的, 只有更裝逼的.
        preOrder_stack2: function (visit) {
            var stack = new Stack();
            var p = this;
            // 用了一個類似數(shù)組的 stack ,不止能遍歷一個 if 還能遍歷 else 
            // 也就是 能遍歷兩個方向?
            while (p || stack.top){
                if (p) {
                  stack.push(p);
                  p.data && visit(p.data);
                  p = p.leftChild;
                }else {
                  p = stack.pop();
                  p = p.rightChild;
                }
            }
        },
        // 能不能直接用兩個循環(huán)進(jìn)行遍歷? 不用 stack
        preOrder_stack3 : function (visit) {
            var p = this;
            while (p){
                p.data && visit(p.data);
                p = p.leftChild;
            }
            
            p = this.rightChild;
            while (p){
                p.data && visit(p.data);
                p = p.rightChild;
            }
            // 寫到一半我就知道這個不行了, 因為這樣只能遍歷最左一條鏈,和最右的一條鏈,中間的就遍歷不了.
            // 也就是必須要兩個循環(huán)嵌套..
        },
        
        //中序排序 非遞歸方法.
        inOrder_stack1: function (visit) {
            var stack = new Stack();
            stack.push(this);
            
            while (stack.top){
                var p;
                // 向左走到盡頭
                while ((p = stack.peek())){
                    stack.push(p.leftChild);
                }
                stack.pop();
                
                if(stack.top) {
                  p = stack.pop();
                  p.data && visit(p.data);
                  stack.push(p.rightChild);
                }
            }
        },
        inOrder_stack2: function (visit) {
            var stack = new Stack();
            var p = this;
            
            while (p || stack.top){
                if (p) {
                  stack.push(p);
                  p = p.leftChild;
                }else {
                  p = stack.pop();
                  p.data && visit(p.data);
                  p = p.rightChild;
                }
            }
        },
        // 為了區(qū)分兩次過棧的不同處理方式, 在堆棧中增加一個mark域,
        // mark = 0 表示剛剛訪問此節(jié)點, mark = 1 表示左子樹處理結(jié)束返回,
        // mark = 2 表示右子樹處理結(jié)束返回. 每次根據(jù)棧頂?shù)膍ark域決定做何動作
        
        postOrder_stack: function (visit) {
            var stack = new Stack();
            stack.push([this,0]);
            
            while (stack.top){
                var a = stack.pop();
                var node = a[0];
                
                switch (a[1]){
                    case 0:
                      stack.push([node,1]);// 修改 mark 域
                      if(node.leftChild) stack.push([node.leftChild,0]);
                        break;
                    case 1:
                      stack.push([node,2]);
                      if (node.rightChild) stack.push([node.rightChild,0]);
                      break;
                    case 2:
                       node.data && visit(node.data);
                      break;
                    default:
                        break;
                }
            }
        },
        // 還是很秀..消化困難.
        
        
        //遞歸版本 先序
        preOrderTraverse: function (visit) {
            visit(this.data);
            if (this.leftChild) preOrderTraverse.call(this.leftChild,visit);
            if (this.rightChild) preOrderTraverse.call(this.rightChild,visit);
        },
        // 遞歸版 中序
        inOrderTraverse : function (visit) {
          if (this.leftChild) inOrderTraverse.call(this.leftChild,visit);
          visit(this.data);
          if (this.rightChild) inOrderTraverse.call(this.rightChild,visit);
        },
        // 遞歸版 后序
        postOrderTraverse : function (visit) {
          if (this.leftChild) postOrderTraverse.call(this.leftChild,visit);
          if (this.rightChild) postOrderTraverse.call(this.rightChild,visit);
          visit(this.data);
        },
        // 原來遞歸真的比循環(huán)更簡潔嗎?
        
        levelOrderTraverse : function (visit) {
            var queue = new Queue();// 這個js也沒見過.
            // 這個似乎是 系統(tǒng)自帶的一個模塊之一. 系統(tǒng)組件之一.
            // 用來創(chuàng)建,先入先出的東西?
            //https://msdn.microsoft.com/zh-cn/library/system.collections.queue(v=vs.110).aspx
            // 好像還不是上面這個組件.
            // enQueue 就先簡單理解成push
            // queue 是隊列的意思..
            // 講解 https://blog.csdn.net/dengpei187/article/details/51880491
            // 隊列(Queue)是只允許在一端進(jìn)行插入工作,而在另一端進(jìn)行刪除操作的線性表岁经。隊列是一種先進(jìn)先出(First In First Out)的線性表汁蝶,簡稱FIFO着帽。允許插入的一端稱為隊尾揣钦,允許刪除的一端稱為隊頭获询。
            queue.enQueue(this);
            while (queue.rear){ // 最后一個元素的下一個元素,循環(huán),所以是第一個元素. 不深究,咱先把本篇抄錄一下再說.
                var p = queue.deQueue ();// 就相當(dāng)于 shift 方法?
                p.data && visit(p.data);
                p.leftChild && queue.enQueue(p.leftChild);
                p.rightChild && queue.enQueue(p.rightChild);
            }
        },
        
        //求先序序列為k的節(jié)點的值
        getPreSequence : function (k) {
            var count = 0;
            
            void function recurse (node) {
                if (node) {
                  if (++count === k) {
                    console.log('Value is: ' + node.data);
                  } else {
                    recurse(node.leftChild);
                    recurse(node.rightChild);
                  }
                }
            }(this);
        },
        
        // 求二叉樹中葉子節(jié)點的數(shù)目.
        
        countLeaves: function () {
            return function recurse (node) {
                if (!node) return 0;
                else if (!node.leftChild && !ndoe.rightChild) return 1;
                else return recurse(node.leftChild) + recurse(node.rightChild);
            }(this);
        },
        
        // 交換所有節(jié)點的左右子樹
        revoluteBinaryTree : function revoluteBinaryTree () {
            var temp = this.leftChild;
            this.leftChild = this.rightChild;
            this.rightChild = temp;
            
            if (this.leftChild) revoluteBinaryTree.call(this.leftChild);
            if (this.rightChild) revoluteBinaryTree.call(this.rightChild);
        },
        
        // 求二叉樹中以值為x的節(jié)點為根的子樹深度
        getSubDepth : function getSubDepth (x) {
            if (this.data === x) {
                console.log('subDepth: ' + this.getDepth());// 這個函數(shù)應(yīng)該在下面定義了.
            } else{
                if (this.leftChild) getSubDepth.call(this.leftChild, x);
                if (this.rightChild) getSubDepth.call(this.rightChild, x);
            }
        },
        // 返回二叉樹的深度.
        getDepth: function getDepth () {
            if (this === global) return 0;
            else {
              var m = getDepth.call(this.leftChild);
              var n = getDepth.call(this.rightChild);
              return (m > n ? m : n) + 1;// 我了個擦, 這個 + 1 是神來之筆嗎?
            }
        },
        // 刪除所有以元素x為根的子樹
        delSubX : function delSubX (x) {
            if (this.data === x) {
                this.leftChild = null;
                this.rightChild = null;
            } else {
              if (this.leftChild) delSubX.call(this.leftChild,x);// 原文應(yīng)該是忘了傳這個x了.
              if (this.rightChild) delSubX.call(this.rightChild,x);
            }
            // 這個版本和 博客一相比, 博客一里的需求是把后面的樹給連上, 這里是直接刪除整個樹.
        },
        // 非遞歸賦值二叉樹
        copyBinaryTree_stack : function () {
            // 用來存放本體節(jié)點的棧
            var stack1 = new Stack();
            // 用來存放新二叉樹節(jié)點的棧
            var stack2 = new Stack();
            stack1.push(this);
            var newTree = new BinaryTree();
            var q = newTree;
            stack2.push(newTree);
            var p;
            
            while (stack1.top){
                // 向左走到盡頭
                while ((p = stack1.peek())){
                    if (p.leftChild) q.leftChild = new BinaryTree();
                    q = q.leftChild;
                    stack1.push(p.leftChild);
                    stack2.push(q);
                }
                
                p = stack1.pop();
                q = stack2.pop();
                
                if (stack1.top) {
                  p = stack1.pop();
                  q = stack2.pop();
                  if (p.rightChild) q.rightChild = new BinaryTree();
                  q.data = p.data;
                  q = q.rightChild;
                  stack1.push(p.rightChild); // 向右一步
                  stack2.push(q);
                }
            }
            return newTree;
        },
        // 求二叉樹中節(jié)點p和q的最先祖先
        findNearAncient : function (pNode,qNode) {
            var pathP = [];
            var pathQ = [];
            findPath(this, pNode, pathP, 0);
            findPath(this, qNode, pathQ, 0);
            
            for (var i = 0; pathP[i] == pathQ[i] && pathP[i];i++);
            // 這又是什么秀操作? 明白了..
            return pathP[--i];
        },
        toString : function () {
            // 這是用來干嘛的?
        },
        // 求一顆二叉樹的繁茂度.
        // 繁茂度的定義:各層節(jié)點數(shù)的最大值與樹的高度的乘積 
        lunshDegree : function () {
            var countArr = [];
            var queue = new Queue();
            queue.enQueue({
              node: this,
              layer: 0// 用來表示在幾層.
            });
            // 利用層序遍歷來統(tǒng)計各層的節(jié)點數(shù)
            var r;
            while (queue.rear){
                r = queue.deQueue();// deQueue 就相當(dāng)于是  pop來著? 
                countArr[r.layer] = (countArr[r.layer] || 0) + 1;
                // 2.只要同一層級的再次出現(xiàn),就 +1;
                // 我剛開始錯誤的認(rèn)為 countArr[r.layer] = r.layer//導(dǎo)致我一直想不通,覺得max只能是countArr[last]
                if (r.node.leftChild) {
                  queue.enQueue({
                    node:r.node.leftChild,
                    layer:r.layer + 1
                  });
                }
                if (r.node.rightChild) {
                  queue.enQueue({
                    node: r.node.rightChild,
                    layer: r.layer + 1
                  });
                }
                // 1.先給在同一層級的節(jié)點進(jìn)行標(biāo)記,在幾層. 2在上面
            }
            //最后一個隊列元素所在層就是樹的高度
            var height = r.layer;
            for (var max = counArr[0],i = 1;countArr[i];i++) {
              //求層最大節(jié)點數(shù)
              if(countArr[i] > max) max = countArr[i];
            }
            return height * max;// 繁茂度的定義就是這個..
            //真是,從頭到尾一直秀..難道是我基礎(chǔ)太差了?
        },
        // 求深度等于樹的高度減一的最靠左的節(jié)點.
        printPath_maxDepthS1: function () {
            var maxh = this.getDepth();
            var path = [];
            
            if (maxh < 2) return false;//表示只有一個節(jié)點.
            
            find_h(this,1);
            
            function find_h (tree,h) {
                path[h] = tree;
                
                if (h == maxh - 1) {
                  var s = ' ';
                  for (var i = 1; path[i]; i++) s += path[i].data + (path[i + 1] ? '->' : '');
                  // 這什么鬼? 無論 if 還是 for 來個空格就可以把 {} 省略? 測試發(fā)現(xiàn)確實這樣.
                  // 看來我真實小白..
                  console.log(s);
                  return;
                }else {
                  if (tree.leftChild) find_h(tree.leftChild, h + 1);
                  if (tree.rightChild) find_h(tree.rightChild, h + 1);
                }
                path[h] = null;
                // 
            }
        },
        //求樹節(jié)點的子孫總數(shù)填入descNum域中, 并返回
        descNum : function () {
            return function recurse (node) {
                var d ;
                if (!node) return -1;
                else d = recurse(node.leftChild) + recurse(node.rightChild) + 2;
                
                node.desNum = d;
                return d;
            }(this);
        }
      }// 原型鏈上的結(jié)束
      
      //判斷二叉樹是否完全二叉樹
      BinaryTree.isFullBinaryTree = function (tree) {
        var queue = new Queue();
        var flag = 0;
        queue.enQueue(tree);
        
        while (queue.rear){// 如果隊列不為空, 依然return false,就表明leftChild和rightChild當(dāng)中有一個是null
          // 不對啊, 如果 queue.rear 指的是最后一個元素的下一個,那么這個循環(huán)不合理啊..
            var p = queue.deQueue();// 也就是 非完全二叉樹
            //
            if(!p) flag = 1;
            else if (flag) return false;
            // 為什么  這兩句 不直接改成 if (!p) return false;? 為什么要借助flag,再走一圈?
            // 因為完全二叉樹的最后一個元素
            else {
              queue.enQueue(p.leftChild);// 前面是不是要添加 if(p.leftChild)啊?
              queue.enQueue(p.rightChild);// p.rightChild == null時 應(yīng)該也會放進(jìn)隊列里.
            }
        }
        return true;
        // *** 這個函數(shù)的邏輯沒想通.
      }
      
      
      
      function findPath (tree, node,path,i) {// 這個為什么不放在原型鏈上?因為有可能處理的數(shù)據(jù)和this樹無關(guān)?
        var found = false;
        
        void function recurse (tree, i) {
            if (tree == node) {
                found = true;
                return;// 這個函數(shù)不需要返回? 因為整個過程我們遞歸用的都是同一個path,遞歸結(jié)束之后,path也就生成了.
                // 我現(xiàn)在覺得這篇代碼的價值根本不在什么二叉樹是什么玩意,
                // 這篇代碼的價值是,簡直就是各種花樣寫遞歸的教材嘛..
                // 當(dāng)然還有 for循環(huán).
            }
            
            path[i] = tree;
            if (tree.leftChild) recurse(tree.leftChild, i + 1);
            if (tree.rightChild && !found) recurse(tree.rightChild, i + 1);
            if (!found) path[i] = null;
        }(tree,i);
      }
      
      var global = Function ('return this;')();
      
      // 一下就是測試上面寫的函數(shù)
      void function test () {
        var tree = [1,2,3,4,5,,6,,,7];
        var test = new BinaryTree();
        test.createBinaryTree(tree);
        test.preOrderTraverse(function (value) {
            console.log('preOrder: ' + value);
        });
        test.inOrderTraverse(function (value) {
            console.log('inOrder: ' + value);
        });
        test.postOrderTraverse(function (value) {
            console.log('postOrder: ' + value);
        });
        
        test.preOrder_stack(function (data) {
            console.log('preOrderNonRecusive: ' + data);
        });
        test.preOrder_stack2(function (data) {
            console.log('preOrder_stack2: ' + data);
        });
        test.inOrder_stack1(function (value) {
            console.log('inOrder_stack1: ' + value);
        });
        test.inOrder_stack2(function (value) {
            console.log('inOrder_stack2: ' + value);
        });
        test.postOrder_stack(function (value) {
            console.log('postOrder_stack: ' + value);
        });
        test.getPreSequence(5);
        console.log(test.countLeaves());
        test.getSubDepth(6);
        test.getSubDepth(2);
        test.levelOrderTraverse(function (value) {
            console.log('levelOrderTraverse: ' + value);
        });
        
        var newTree = test.copyBinaryTree_stack();
        
        var node1 = test.leftChild.leftChild;
        var node2 = test.leftChild.rightChild.leftChild;
        var ancient = test.findNearAncient(node1,node2);
        console.log(ancient);
        console.log('expect false: ' + BinaryTree.isFullBinaryTree(newTree));
        console.log('lush degree: ' + test.lunshDegree());
        
        test.printPath_maxDepthS1();
        console.log(test.descNum());
      }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涨岁,一起剝皮案震驚了整個濱河市拐袜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梢薪,老刑警劉巖蹬铺,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異秉撇,居然都是意外死亡甜攀,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門琐馆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赴邻,“玉大人,你說我怎么就攤上這事啡捶±蚜玻” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵瞎暑,是天一觀的道長彤敛。 經(jīng)常有香客問我,道長了赌,這世上最難降的妖魔是什么墨榄? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮勿她,結(jié)果婚禮上袄秩,老公的妹妹穿的比我還像新娘。我一直安慰自己逢并,他們只是感情好之剧,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著砍聊,像睡著了一般背稼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玻蝌,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天蟹肘,我揣著相機(jī)與錄音,去河邊找鬼俯树。 笑死帘腹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的许饿。 我是一名探鬼主播阳欲,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胸完?” 一聲冷哼從身側(cè)響起书释,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赊窥,沒想到半個月后爆惧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡锨能,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年扯再,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片址遇。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡熄阻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出倔约,到底是詐尸還是另有隱情秃殉,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布浸剩,位于F島的核電站钾军,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏绢要。R本人自食惡果不足惜吏恭,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望重罪。 院中可真熱鬧樱哼,春花似錦、人聲如沸剿配。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惨篱。三九已至盏筐,卻和暖如春围俘,著一層夾襖步出監(jiān)牢的瞬間砸讳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工界牡, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留簿寂,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓宿亡,卻偏偏與公主長得像常遂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挽荠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

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

  • 二叉樹有前序克胳、中序平绩、后序遍歷
    下一站深圳閱讀 456評論 0 3
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,079評論 25 707
  • 有三個人要被關(guān)進(jìn)監(jiān)獄里,他們是一個美國人漠另,一個法國人捏雌,一個以色列的猶太人,刑期三年笆搓。監(jiān)獄長讓三個犯人一人提一個要求...
    斯麥爾閱讀 2,368評論 0 3
  • (寫于12年12月2日晚) 秋風(fēng)起性湿,秋葉落,被吹落的又何止是葉子满败,還有那顆冰冷的心肤频。 秋風(fēng)無情,將秋葉吹滿地算墨,流水...
    剎那芳華丶丶閱讀 579評論 0 2
  • 日行一善簽到 姓名 :張文達(dá) (單位)哈爾濱中央紅小月亮超市有限責(zé)任公司 【日精進(jìn)打卡第145天】20180817...
    文達(dá)_心動驛站閱讀 276評論 0 0