算法 二叉树 单向链表\双向链表\循环链表

数据结构的存储
数据结构的存储一般常
用的有两种 顺序存储结构 和 链式存储结构
 2.1 顺序存储结构

发挥想象力啊。 举个列子。数组。1-2-3-4-5-6-7-8-9-10。这个就是一个顺序存储结构 ,存储是按顺序的 举 例说明啊。 栈。做开发的都熟悉。栈是先进后出 ,后进先出的形式 对不对 ?!他的你可以这样理解
hello world 在栈里面从栈底到栈顶的逻辑依次为 h-e-l-l-o-w-o-r-l-d 这就是顺序存储 再比如 队列 ,队列 是先进先出的对吧,从头到尾 h-e-l-l-o-w-o-r-l-d 就是这样排对的
 2.2 链式存储结构

再次发挥想象力 这个稍微复杂一点 这个图片我一直弄好 ,回头找美工问问,再贴上 例如 还是一个数组
1-2-3-4-5-6-7-8-9-10 链式存储就不一样了 1(地址)-2(地址)-7(地址)-4(地址)-5(地址)-9(地址)-8(地址)-3(地 址)-6(地址)-10(地址)。每个数字后面跟着一个地址 而且存储形式不再是顺序 ,也就说顺序乱了,1(地址) 1 后面跟着的这个地址指向的是 2,2 后面的地址指向的是 3,3 后面的地址指向是谁你应该清楚了吧。他 执行的时候是 1(地址)-2(地址)-3(地址)-4(地址)-5(地址)-6(地址)-7(地址)-8(地址)-9(地址)-10(地址),但是存储 的时候就是完全随机的。明白了?!

单向链表\双向链表\循环链表
还是举例子。理解最重要。不要去死记硬背 哪些什么。定义啊。逻辑啊。理解才是最重要滴

3.1 单向链表
A->B->C->D->E->F->G->H. 这就是单向链表 H 是头 A 是尾 像一个只有一个头的火车一样 只能一个头拉
着跑

3.2 双向链表

数组和链表区别:
数组:数组元素在内存上连续存放,可以通过下标查找元素;插入、删除需要移动大量元素,比较适用元
素很少变化的情况
链表:链表中的元素在内存中不是顺序存储的,查找慢,插入、删除只需要对元素指针重新赋值,效率高

3.3 循环链表
循环链表是与单向链表一样,是一种链式的存储结构,所不同的是,循环链表的最后一个结点的指针是指 向该循环链表的第一个结点或者表头结点,从而构成一个环形的链。发挥想象力 A->B->C->D->E->F->G->H->A. 绕成一个圈。就像蛇吃自己的这就是循环 不需要去死记硬背哪些理论知识。

4.1 什么是二叉树
树形结构下,两个节点以内 都称之为二叉树 不存在大于 2 的节点 分为左子树 右子树 有顺序 不能颠 倒 ,懵逼了吧,你肯定会想这是什么玩意,什么左子树右子树 ,都什么跟什么鬼? 现在我以普通话再讲 一遍,你把二叉树看成一个人 ,人的头呢就是树的根 ,左子树就是左手,右子树就是右手,左右手可以 都没有(残疾嘛,声明一下,绝非歧视残疾朋友,勿怪,勿怪就是举个例子,i am very sorry) , 左右 手呢可以有一个,就是不能颠倒。这样讲应该明白了吧

二叉树有五种表现形式
1.空的树(没有节点)可以理解为什么都没 像空气一样
2.只有根节点。 (理解一个人只有一个头 其他的什么都没,说的有点恐怖) 3.只有左子树 (一个头 一个左手 感觉越来越写不下去了)
4.只有右子树
5.左右子树都有
二叉树可以转换成森林 树也可以转换成二叉树。这里就不介绍了 你做项目绝对用不到 数据结构大致介绍这么多吧。理解为主, 别死记,死记没什么用

1、不用中间变量,用两种方法交换 A 和 B 的值

1001.png

2、求最大公约数


1002.png

3、模拟栈操作
 栈是一种数据结构,特点:先进后出 -
 练习:使用全局变量模拟栈的操作

include <stdio.h> #include <stdbool.h> #include <assert.h>

//保护全局变量:在全局变量前加 static 后,这个全局变量就只能在本文件中使用 static int data[1024];//栈最多能保存 1024 个数据
static int count = 0;//目前已经放了多少个数(相当于栈顶位置)


1003.png

4、排序算法
选择排序、冒泡排序、插入排序三种排序算法可以总结为如下:
都将数组分为已排序部分和未排序部分。
1.选择排序将已排序部分定义在左端,然后选择未排序部分的最小元素和未排序部分的第一个元素交换。 2.冒泡排序将已排序部分定义在右端,在遍历未排序部分的过程执行交换,将最大元素交换到最右端。 3.插入排序将已排序部分定义在左端,将未排序部分元的第一个元素插入到已排序部分合适的位置。 4.1、选择排序
 【选择排序】:最值出现在起始端
 第1趟:在n个数中找到最小(大)数与第一个数交换位置
 第2趟:在剩下n-1个数中找到最小(大)数与第二个数交换位置  重复这样的操作...依次与第三个、第四个...数交换位置
 第n-1趟,最终可实现数据的升序(降序)排列。

/**
 选择排序
 */
void xuanzePaixu() {
    NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"17",@"29",@"35",@"14",@"40", nil];
    for (int i = 0; i < arr.count - 1; i++) {
        for (int j = i + 1; j < arr.count; j++) {
            if ([arr[i] intValue] > [arr[j] intValue]) {
                int temp = [arr[j] intValue];
                arr[j] = arr[i];
                arr[i] = [NSString stringWithFormat:@"%d",temp];
            }
        }
    }
     NSLog(@"%@",arr);
}

4.2、冒泡排序
 【冒泡排序】:相邻元素两两比较,比较完一趟,最值出现在末尾
 第1趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第n
个元素位置
 第2趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第n-1
个元素位置
 ............
 第n-1趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第
2 个元素位置

/**
 冒泡排序
 */
void maoPaoPaixu(void) {
    NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"17",@"29",@"35",@"14",@"40", nil];
    for (int i = 0; i < arr.count; i++) {
        for (int j = 0; j < arr.count - 1 - i; j++) {
            if ([arr[j] intValue] > [arr[j+1] intValue]) {
                int temp = [arr[j] intValue];
                arr[j] = arr[j + 1];
                arr[j+ 1] = [NSString stringWithFormat:@"%d",temp];
            }
        }
    }
    
    NSLog(@"%@",arr);
}

5、折半查找(二分查找)
折半查找:优化查找时间(不用遍历全部数据)
折半查找的原理:
 1> 数组必须是有序的
 2> 必须已知 min 和 max(知道范围)
 3> 动态计算 mid 的值,取出 mid 对应的值进行比较
 4> 如果 mid 对应的值大于要查找的值,那么 max 要变小为 mid-1
 5> 如果 mid 对应的值小于要查找的值,那么 min 要变大为 mid+1
// 已知一个有序数组, 和一个 key, 要求从数组中找到 key 对应的索引位置

/**
 二分查找

 @param ary
 @param findNum
 @return
 */
NSInteger efChazhao(NSArray *ary,NSInteger findNum) {
    NSInteger mid = (ary.count - 1) / 2.0;
    if (mid == 0) {
        return -1; //找不到
    }
    if (findNum == [ary[mid] integerValue]) {
        return mid;//返回所在的序列号
    }
    else if(findNum > [ary[mid] integerValue]) {
        return efChazhao([ary subarrayWithRange:NSMakeRange(mid + 1, ary.count - mid - 1)], findNum);
    }
    else {
        return efChazhao([ary subarrayWithRange:NSMakeRange(0, mid + 1)], findNum);
    }
}
void erfenChazhao() {
    //二分查找一定是有序的数组
    NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"17",@"29",@"35",@"14",@"40", nil];
    NSInteger mid = efChazhao(arr,15);
    NSLog(@"%ld",(long)mid);
}



/**
 快速排序
 */
void ksPaixu(NSMutableArray *arr,NSInteger left,NSInteger right) {
    if(left == right) return;
    NSInteger i = left;
    NSInteger j = right;
    NSInteger key = [arr[left] integerValue];
    while (i < j) {
        while (i < j && key <= [arr[j] integerValue]) {
            j--;
        }
        arr[i] = arr[j];
        while (i<j && key >= [arr[i] integerValue]) {
            I++;
        }
        arr[j] = arr[i];
    }
    arr[i] = [NSString stringWithFormat:@"%ld",(long)key];
    ksPaixu(arr, left, i-1);
    ksPaixu(arr, i+1, right);
}
void kuaisuPaixu() {
    NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"17",@"29",@"35",@"14",@"40", nil];
    ksPaixu(arr, 0, arr.count-1);
    NSLog(@"%@",arr);
}



/**
 插入排序
 */
void charuPaixu() {
    NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"17",@"29",@"35",@"14",@"40", nil];
    for (int i = 1; i<arr.count; i++) {
        int j = I;
        NSInteger temp = [arr[i] integerValue];
        while (j > 0 && temp < [arr[j-1] integerValue]) {
            [arr replaceObjectAtIndex:j withObject:arr[j-1]];
            j--;
        }
        [arr replaceObjectAtIndex:j withObject:[NSString stringWithFormat:@"%ld",(long)temp]];
    }
    NSLog(@"%@",arr);
}


/**
 希尔排序
 */
void xierPaixu() {
    NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"17",@"29",@"35",@"14",@"40", nil];
    int gap = arr.count / 2.0;
    while (gap >= 1) {
        for (int i = gap; i < arr.count; i++) {
            NSInteger temp = [arr[i] integerValue];
            int j = I;
            while (j >= gap && temp < [arr[j- gap] integerValue]) {
                [arr replaceObjectAtIndex:j withObject:arr[j-gap]];
                j-=gap;
            }
            [arr replaceObjectAtIndex:j withObject:[NSString stringWithFormat:@"%ld",(long)temp]];
        }
        gap = gap / 2.0;
    }
    NSLog(@"%@",arr);
}

字符串反正
给定字符串 "hello,world",实现将其反转。输出结果:dlrow,olleh

- (NSString *)reversalString:(NSString *)originString{
    NSString *resultStr = @"";
    for (NSInteger i = originString.length -1; i >= 0; i--) {
      NSString *indexStr = [originString substringWithRange:NSMakeRange(i, 1)];
      resultStr = [resultStr stringByAppendingString:indexStr];
    }
  return resultStr;
}

void char_reverse(char *cha){
  char *begin = cha;
  char *end = cha + strlen(cha) - 1;
  while (begin <= end) {
    char temp = *end;
    *(end--) = *begin;
    *(begin++) = temp;
  }
}
// 调用
  char cha[] = "hello,world";
  char_reverse(cha);
  printf("%s",cha);
  结果:dlrow,olleh

序数组合并
将有序数组 {1,4,6,7,9} 和 {2,3,5,6,8,9,10,11,12} 合并为 {1,2,3,4,5,6,6,7,8,9,9,10,11,12}

2001.png
// 将有序数组a和b的值合并到一个数组result当中,且仍然保持有序
void mergeList(int a[], int aLen, int b[], int bLen, int result[]);


void mergeList(int a[], int aLen, int b[], int bLen, int result[])
{
    int p = 0; // 遍历数组a的指针
    int q = 0; // 遍历数组b的指针
    int i = 0; // 记录当前存储位置
    
    // 任一数组没有到达边界则进行遍历
    while (p < aLen && q < bLen) {
        // 如果a数组对应位置的值小于b数组对应位置的值
        if (a[p] <= b[q]) {
            // 存储a数组的值
            result[i] = a[p];
            // 移动a数组的遍历指针
            p++;
        }
        else{
            // 存储b数组的值
            result[i] = b[q];
            // 移动b数组的遍历指针
            q++;
        }
        // 指向合并结果的下一个存储位置
        i++;
    }
    
    // 如果a数组有剩余
    while (p < aLen) {
        // 将a数组剩余部分拼接到合并结果的后面
        result[i] = a[p++];
        i++;
    }
    
    // 如果b数组有剩余
    while (q < bLen) {
        // 将b数组剩余部分拼接到合并结果的后面
        result[i] = b[q++];
        i++;
    }
}

HASH 算法
 哈希表
例:给定值是字母 a,对应 ASCII 码值是 97,数组索引下标为 97。
这里的 ASCII 码,就算是一种哈希函数,存储和查找都通过该函数,有效地提高查找效率。
 在一个字符串中找到第一个只出现一次的字符。如输入"abaccdeff",输出'b'字符(char)是一个长度为8 的数据类型,因此总共有 256 种可能。每个字母根据其 ASCII 码值作为数组下标对应数组种的一个数 字。数组中存储的是每个字符出现的次数。

2002.png

查找两个子视图的共同父视图 思路:分别记录两个子视图的所有父视图并保存到数组中,然后倒序寻找,直至找到第一个不一样的父视图。

2003.png
// 查找两个视图的共同父视图
- (NSArray<UIView *> *)findCommonSuperView:(UIView *)view other:(UIView *)viewOther;

- (NSArray <UIView *> *)findCommonSuperView:(UIView *)viewOne other:(UIView *)viewOther
{
    NSMutableArray *result = [NSMutableArray array];
    
    // 查找第一个视图的所有父视图
    NSArray *arrayOne = [self findSuperViews:viewOne];
    // 查找第二个视图的所有父视图
    NSArray *arrayOther = [self findSuperViews:viewOther];
    
    int i = 0;
    // 越界限制条件
    while (i < MIN((int)arrayOne.count, (int)arrayOther.count)) {
        // 倒序方式获取各个视图的父视图
        UIView *superOne = [arrayOne objectAtIndex:arrayOne.count - i - 1];
        UIView *superOther = [arrayOther objectAtIndex:arrayOther.count - i - 1];
        
        // 比较如果相等 则为共同父视图
        if (superOne == superOther) {
            [result addObject:superOne];
            i++;
        }
        // 如果不相等,则结束遍历
        else{
            break;
        }
    }
    
    return result;
}

- (NSArray <UIView *> *)findSuperViews:(UIView *)view
{
    // 初始化为第一父视图
    UIView *temp = view.superview;
    // 保存结果的数组
    NSMutableArray *result = [NSMutableArray array];
    while (temp) {
        [result addObject:temp];
        // 顺着superview指针一直向上查找
        temp = temp.superview;
    }
    return result;
}






- (void)viewDidLoad {
    [super viewDidLoad];
    Class commonClass1 = [self commonClass1:[ViewA class] andClass:[ViewC
class]];
    NSLog(@"%@",commonClass1);
    //      2018-03-22 17:36:01.868966+0800[84288:2458900] ViewD
}
//获取所有父类
- (NSArray *)superClasses:(Class)class {
    if (class == nil) {
        return @[];
    }
    NSMutableArray *result = [NSMutableArray array];
    while (class != nil) {
        [result addObject:class];
        class = [class superclass];
    }
    return [result copy];
}
- (Class)commonClass1:(Class)classA andClass:(Class)classB {
    NSArray *arr1 = [self superClasses:classA];
    NSArray *arr2 = [self superClasses:classB];
    for (NSUInteger i = 0; i < arr1.count; ++i) {
        Class targetClass = arr1[i];
        for (NSUInteger j = 0; j < arr2.count; ++j) {
            if (targetClass == arr2[j]) {
                return targetClass;
} }
}
return nil; 
}

- (Class)commonClass2:(Class)classA andClass:(Class)classB{
    NSArray *arr1 = [self superClasses:classA];
    NSArray *arr2 = [self superClasses:classB];
    NSSet *set = [NSSet setWithArray:arr2];
    for (NSUInteger i =0; i<arr1.count; ++i) {
        Class targetClass = arr1[i];
        if ([set containsObject:targetClass]) {
            return targetClass;
        }
}
return nil; 
}






/**
 求无序数组当中的中位数(快排思想,选中关键字,高低交替扫描)
 示例:
[@"1",@"9",@"6",@"8",@"3",@"2"]
 输出:
@"3"
 */

+ (void)findMedianValue {undefined

    NSMutableArray *array = [NSMutableArray arrayWithObjects:@"1",@"9",@"6",@"8",@"3",@"2", nil];

    NSLog(@"输入数据:%@",array);

    NSInteger low = 0;

    NSInteger high = array.count - 1;

    

    NSInteger mid = high/2;

    NSInteger result = [self arraySort:array IndexStart:low IndexEnd:high];

    while(result != mid) {undefined

        if (result < mid) {undefined

            result = [self arraySort:array IndexStart:result+1 IndexEnd:high];

        }else {undefined

            result = [self arraySort:array IndexStart:low IndexEnd:result-1];

        }

    }

    NSLog(@"中位数是:%@",array[mid]);

}

 

+ (NSInteger)arraySort:(NSMutableArray *)array IndexStart:(NSInteger)indexStart IndexEnd:(NSInteger)indexEnd {undefined

    

    NSInteger keyValue = [array[indexEnd] integerValue];

    NSInteger lastEnd = indexEnd;

    

    while (indexStart < indexEnd) {undefined

        while (indexStart < indexEnd && [array[indexStart] integerValue] <= keyValue) {undefined

            indexStart++;

        }

        while (indexStart < indexEnd && [array[indexEnd] integerValue] >= keyValue) {undefined

            indexEnd--;

        }

        if (indexStart < indexEnd) {undefined

            NSString *temp = array[indexStart];

            array[indexStart] = array[indexEnd];

            array[indexEnd] = temp;

        }

    }

    NSString *temp = array[indexEnd];

    array[indexEnd] = array[lastEnd];

    array[lastEnd] = temp;

    return indexStart;    

}


//给定一个整数数组和一个目标值,找出数组中和为目标值得的俩个数
//给定nums = [2,7,11,15]  ,target = 9 -------返回【0,1】

 ● 第一层for循环从索引0到倒数第二个索引拿到每个数组的元素
 ●第二个for循环遍历上一层for循环拿到的元素的后面得所有元素
class Solution {
    public int[] twoSum(int[] nums, int target) {
       int len = nums.length;
        int[] result = new int[2];
        for(int i = 0; i < len; i++){
            for(int j = i+1; j < len; j++){
                if(nums[i] + nums[j] == target){
                    result[0] = i;
                    result[1] = j;
                    return result;
} }
}
        return result;
    }
}

//查找第一个只出现一次的字符(hash查找)
# define SIZE 256
char GetChar(char str[])
{
  if(!str)
    return 0;
  char* p = NULL;
  unsigned count[SIZE] = {0};
  char buffer[SIZE];
  char* q = buffer;
  for(p=str; *p!=0; p++)
  {
    if(++count[(unsigned char)*p] == 1)
      *q++ = *p;
}
  for (p=buffer; p<q; p++)
  {
    if(count[(unsigned char)*p] == 1)
    return *p;
  }
  return 0; 
}

char findFirstChar(char* cha)
{
    char result = '\0';
    // 定义一个数组 用来存储各个字母出现次数
    int array[256];
    // 对数组进行初始化操作
    for (int i=0; i<256; i++) {
        array[i] =0;
    }
    // 定义一个指针 指向当前字符串头部
    char* p = cha;
    // 遍历每个字符
    while (*p != '\0') {
        // 在字母对应存储位置 进行出现次数+1操作
        array[*(p++)]++;
    }
    
    // 将P指针重新指向字符串头部
    p = cha;
    // 遍历每个字母的出现次数
    while (*p != '\0') {
        // 遇到第一个出现次数为1的字符,打印结果
        if (array[*p] == 1)
        {
            result = *p;
            break;
        }
        // 反之继续向后遍历
        p++;
    }
    
    return result;
}


// 无序数组查找中位数
    int list[10] = {12,3,10,8,6,7,11,13,9};
    // 3 6 7 8 9 10 11 12 13
    //         ^
    int median = findMedian(list, 10);
    printf("the median is %d \n", median);


//求一个无序数组的中位数
int findMedian(int a[], int aLen)
{
    int low = 0;
    int high = aLen - 1;
    
    int mid = (aLen - 1) / 2;
    int div = PartSort(a, low, high);
    
    while (div != mid)
    {
        if (mid < div)
        {
            //左半区间找
            div = PartSort(a, low, div - 1);
        }
        else
        {
            //右半区间找
            div = PartSort(a, div + 1, high);
        }
    }
    //找到了
    return a[mid];
}

int PartSort(int a[], int start, int end)
{
    int low = start;
    int high = end;
    
    //选取关键字
    int key = a[end];
    
    while (low < high)
    {
        //左边找比key大的值
        while (low < high && a[low] <= key)
        {
            ++low;
        }
        
        //右边找比key小的值
        while (low < high && a[high] >= key)
        {
            --high;
        }
        
        if (low < high)
        {
            //找到之后交换左右的值
            int temp = a[low];
            a[low] = a[high];
            a[high] = temp;
        }
    }
    
    int temp = a[high];
    a[high] = a[end];
    a[end] = temp;
    
    return low;
}


定义一个链表

// 定义一个链表
struct Node {
    int data;
    struct Node *next;
};

@interface ReverseList : NSObject
// 链表反转
struct Node* reverseList(struct Node *head);
// 构造一个链表
struct Node* constructList(void);
// 打印链表中的数据
void printList(struct Node *head);

@end

#import "ReverseList.h"

@implementation ReverseList

struct Node* reverseList(struct Node *head)
{
    // 定义遍历指针,初始化为头结点
    struct Node *p = head;
    // 反转后的链表头部
    struct Node *newH = NULL;
    
    // 遍历链表
    while (p != NULL) {
        
        // 记录下一个结点
        struct Node *temp = p->next;
        // 当前结点的next指向新链表头部
        p->next = newH;
        // 更改新链表头部为当前结点
        newH = p;
        // 移动p指针
        p = temp;
    }
    
    // 返回反转后的链表头结点
    return newH;
}

struct Node* constructList(void)
{
    // 头结点定义
    struct Node *head = NULL;
    // 记录当前尾结点
    struct Node *cur = NULL;
    
    for (int i = 1; i < 5; i++) {
        struct Node *node = malloc(sizeof(struct Node));
        node->data = i;
        
        // 头结点为空,新结点即为头结点
        if (head == NULL) {
            head = node;
        }
        // 当前结点的next为新结点
        else{
            cur->next = node;
        }
        
        // 设置当前结点为新结点
        cur = node;
    }
    
    return head;
}

void printList(struct Node *head)
{
    struct Node* temp = head;
    while (temp != NULL) {
        printf("node is %d \n", temp->data);
        temp = temp->next;
    }
}

@end
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容