iOS 算法大全

算法其实在实际应用中比较少,因为一般的APP用不到算法也可以很好的开发,但如果真的用到的还是很不好找的,我就在网上收集一些

1.线性查找

/// 冒泡排序
+ (void)bubbleSortWithArray:(NSMutableArray *)array withFirst:(NSInteger)first withEnd:(NSInteger)end{
for (NSInteger i = first ; i < end; i++) {
for (NSInteger j = end; j > i; j--) {
if (array[j] < array[j-1]) {
id temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
}
}
}
}

+ (void)bubbleSortWithArray:(NSMutableArray *)array{
return [self bubbleSortWithArray:array withFirst:0 withEnd:[array count] - 1];
}

//求取最小的k个数
//数组a中从a[p]到a[r]的元素按照x划分,大于或者等于x的在右边,小于x的在左边
+ (NSInteger)partitionModify:(NSMutableArray *)a withP:(NSInteger)p withR:(NSInteger)r withX:(NSInteger)x{
NSInteger i,j;

j = r;

for (i = p; i < j; i++) {
    if ([a[i] integerValue] >= x) {
        while (i<j && [a[j] integerValue] >= x) j--;
        if (i != j) {
            id t = a[i];
            a[i] = a[j];
            a[j] = t;
            j--;
        }
        else break;
    }
    }          /*上面的循环结束分为几种情况
 1 i > j 此时必定有 a[i] >= x,否则 a[j+1] = a[i] < x 与 a[j+1] >= x 矛盾 ,如果不是边界,进入if语句
 2 i = j 此时如果 a[i] < x 则a[i+1] = a[j+1] >x 返回 i
 3 当i==p,此时直接返回边界元素下标
 4 当i == r,此时为右边界,此时a[i]肯定为x,返回i - 1,也即r - 1
 */

if ([a[i] integerValue] >= x && i > p) {
    return i - 1;
}
return i;
}

//将r-p+1个数据按五个元素分为一组,分别找出各组的中位数,
//再将各组的中位数与数组开头的数据在组的顺序依次交换,对这些各组的中位数
//按同样的方法继续求出中位数,最后得出的整个数组的中位数,利用中位数就可以将数据按照与中位数的比较来划分
+ (NSInteger)selectModify:(NSMutableArray *)array withP:(NSInteger)p withR:(NSInteger)r withK:(NSInteger)k{
NSInteger i;
if (r - p + 1 <= 5) {
[self bubbleSortWithArray:array withFirst:p withEnd:r];
return [array[p + k - 1] integerValue];
}

//将r-p+1个数据按五个元素分为一组,可以分为(r - p + 1) / 5组
//分别找出各组的中位数,再将各组的中位数与数组开头的数据按组的顺序依次交换
for (i = 0; i < (r-p+1)/5;i++ ) {
    NSInteger s = p + 5*i,t=s+4;
    [self bubbleSortWithArray:array withFirst:s withEnd:t];
    id temp = array[p + i];
    array[p + i] = array[s + 2];
    array[s + 2] = temp;
}
//对这些各组的中位数
//按同样的方法继续求出中位数,最后得出的整个数组的中位数 x
NSInteger x = [self selectModify:array withP:p withR: p + (r - p + 1) / 5 - 1 withK:(r - p + 6) / 10];

i = [self partitionModify:array withP:p withR:r withX:x];

NSInteger j = i - p + 1;

if (k <= j) {
    return [self selectModify:array withP:p withR:i withK:k];
}else{
    return [self selectModify:array withP:i+1 withR:r withK:k-j];
}
}


+ (NSInteger)selectModify:(NSMutableArray *)array withNum:(NSInteger)n{
if (n == 0 || n > [array count]) return -1;// 未查到

return [self selectModify:array withP:0 withR:[array count] - 1 withK:n];
}

2.插入排序

+ (void)insertSort:(NSMutableArray *)list{
for (int i = 1; i < [list count]; i++) {
    int j = i;
    NSInteger temp = [[list objectAtIndex:i] integerValue];
    while (j >0 && temp < [[list objectAtIndex:j - 1] integerValue]) {
        [list replaceObjectAtIndex:j withObject:[list objectAtIndex:(j - 1)]];
        j--;
    }
    [list replaceObjectAtIndex:j withObject:[NSNumber numberWithInteger:temp]];
}
}

  + (void)binaryInsertSort:(NSMutableArray *)list{
    for (int i = 1; i < [list count]; i++) {
    NSInteger temp = [[list objectAtIndex:i] integerValue];
    int left = 0;
    int right = i - 1;
    while (left <= right) {
        int middle = (left + right) / 2;
        if (temp < [[list objectAtIndex:middle] integerValue]) {
            right = middle - 1;
        }else{
            left = middle + 1;
        }
    }
    for (int j = i; j > left; j--) {
        [list replaceObjectAtIndex:j withObject:[list objectAtIndex:j-1]];
    }
    [list replaceObjectAtIndex:left withObject:[NSNumber numberWithInteger:temp]];
    }
    }

3.戴克斯特拉算法

+ (NSArray *)dijkstra_alg:(NSMutableArray *)map  withShotest:(NSMutableArray *)shortest withV:(NSMutableArray *)visited withO:(NSInteger)orig{

NSInteger n = [shortest count];
if ( n - 1 <= 0) return nil;

// 初始化,第一个顶点求出
shortest[orig] = @(0);
visited[orig] = @(YES);

 // 要加入n-1个顶点
for (int p = 0; p != n - 1; p++) {
    // 选出一个距离初始顶点最近的未标记顶点
    int k = -1;
    int min = -1;
    for (int i = 0; i < n; i++) {
        if ([visited[i] compare:@(0)] == NSOrderedSame && [map[orig][i] intValue] != -1) {
            if (min == -1 || min > [map[orig][i] intValue]) {
               
                min = [map[orig][i] intValue];
                k = i;
            }
        }
    }
    // 正确的图生成的矩阵不可能出现K == M的情况
    if (k == -1) {
        NSLog(@"the input map matrix is wrong!");
        return nil;
    }
    
    shortest[k] = @(min);
    visited[k] = @(YES);
    
    for (int i = 0; i < n; i++) {
        
        
        if ([visited[i] compare:@(0)] == NSOrderedSame && [map[k][i] intValue] != -1) {
            int callen = min + [map[k][i] intValue];
            if ([map[orig][i] intValue] == -1 || [map[orig][i] intValue] > callen) {
                map[orig][i] = @(callen);
            }
        }
    }
}
return shortest;
}

+(NSArray *)dijkstra:(NSMutableArray *)map withOrig:(NSInteger)orig{
NSInteger n = [map count];
NSMutableArray *shortest = [NSMutableArray arrayWithCapacity:n];
NSMutableArray *visited = [NSMutableArray arrayWithCapacity:n];
for (int i = 0; i < n; i++) {
    [shortest addObject:@(-1)];
    [visited addObject:@(NO)];
}
return [self dijkstra_alg:map withShotest:shortest withV:visited withO:orig];
}

4.动态规划

+ (NSString *)getRandomString:(NSInteger)length{
NSString *str = @"abcdefghijklmnopqrstuvwxyz";
NSMutableString *res = [[NSMutableString alloc] initWithCapacity:length];
for (int i = 0; i < length; i++) {
    NSRange range;
    range.length = 1;
    range.location = arc4random()%length;
    NSString *r = [str substringWithRange:range];
    [res appendString:r];
}
return res;
}

+ (NSString *)lcs:(NSString *)str1 withOtherString:(NSString *)str2{
int length1 = (int)[str1 length];
int length2 = (int)[str2 length];
NSMutableArray *p1 = [NSMutableArray arrayWithCapacity:length2 + 1];
// 构造二维数组记录子问题x[i]和y[i]的LCS的长度
NSMutableArray *opt = [NSMutableArray arrayWithCapacity:length1 + 1];
for (int i = 0; i < length2 + 1; i++) {
    [p1 addObject:@0];
}

for (int i = 0; i < length1 + 1; i++) {
    [opt addObject:p1];
}



for (int i = length1 - 1; i >= 0; i--) {
    for (int j = length2 - 1; j >= 0; j--) {
        NSRange range1 = {i,1};
        NSRange range2 = {j,1};
        if ([[str1 substringWithRange:range1] isEqualToString:[str2 substringWithRange:range2]]) {
            opt[i][j] = @([opt[i+1][j+1] integerValue] + 1);
        }else{
            int i1 = [opt[i+1][j] intValue] , i2 = [opt[i][j+1] intValue];
            opt[i][j] = @(MAX(i1,i2));
        }
    }
}

int i = 0,j = 0;
NSMutableString *result = [[NSMutableString alloc] init];

while (i < length1 && j < length2) {
    NSRange range1 = {i,1};
    NSRange range2 = {j,1};
    if ([[str1 substringWithRange:range1] isEqualToString:[str2 substringWithRange:range2]]) {
        [result appendString:[str1 substringWithRange:range1]];
        i++;
        j++;
    }else if([opt[i + 1][j] intValue] >= [opt[i][j + 1] intValue]){
        i++;
    }else{
        j++;
    }
}
return result;
}

5.堆排序

/// 最大堆heap 最大/最小优先级队列
+ (void)createBiggestHeap:(NSMutableArray *)list withSize:(int)size beIndex:(int)element{
int lchild = element * 2 + 1,rchild = lchild + 1;//左右子树
while (rchild < size) {//子树均在范围内
//如果比左右子树都小,完成整理
if (list[element] <= list[lchild] && list[element] <= list[rchild]) return;
//如果左边最小
if(list[lchild] <= list[rchild]){
[list exchangeObjectAtIndex:element withObjectAtIndex:lchild];//把左面的提到上面
element = lchild;//循环时整理子树
}else{
//否则右面最小
[list exchangeObjectAtIndex:element withObjectAtIndex:rchild];
element = rchild;
}
lchild = element * 2 + 1;
rchild = lchild + 1;//重新计算子树位置
}
//只有左子树且子树小于自己
if (lchild < size && list[lchild] < list[element]) {
[list exchangeObjectAtIndex:lchild withObjectAtIndex:element];
}
}

//堆排序time:O(nlgn)
+ (void)heapSort:(NSMutableArray *)list{
int i , size;
size = [list count]/1.0;
// 从子树开始整理树
for (i = [list count]/1.0 - 1; i >= 0; i--) {
[self createBiggestHeap:list withSize:size beIndex:i];
}
//拆除树
while (size > 0) {
[list exchangeObjectAtIndex:size - 1 withObjectAtIndex:0];//将根(最小)与数组最末交换
size--;//树大小减小
[self createBiggestHeap:list withSize:size beIndex:0];//整理树
}
}

6.二叉树

/**

  • 生成二叉树
  • @param values 数组
  • @return 二叉树
    */
    + (BinaryTreeNode *)createTreeWithValues:(NSArray *)values {
    BinaryTreeNode *root = nil;
    for (NSInteger i=0; i<values.count; i++) {
    NSInteger value = [(NSNumber *)[values objectAtIndex:i] integerValue];
    root = [[self class] addTreeNode:root value:value];
    }
    return root;
    }

/**

  • 翻转二叉树(非递归)

  • @param rootNode 根节点

  • @return 翻转后的树根节点(其实就是原二叉树的根节点)
    */
    + (BinaryTreeNode *)invertBinaryTreeWithoutRecursion:(BinaryTreeNode *)rootNode {
    if (!rootNode) { return nil; }
    if (!rootNode.leftNode && !rootNode.rightNode) { return rootNode; }
    NSMutableArray *queueArray = [NSMutableArray array]; //数组当成队列
    [queueArray addObject:rootNode]; //压入根节点
    while (queueArray.count > 0) {
    BinaryTreeNode *node = [queueArray firstObject];
    [queueArray removeObjectAtIndex:0]; //弹出最前面的节点,仿照队列先进先出原则
    BinaryTreeNode *pLeft = node.leftNode;
    node.leftNode = node.rightNode;
    node.rightNode = pLeft;

     if (node.leftNode) {
         [queueArray addObject:node.leftNode];
     }
     if (node.rightNode) {
         [queueArray addObject:node.rightNode];
     }
     }
     return rootNode;
     }
    

/**

  • 翻转二叉树(又叫:二叉树的镜像)
  • @param rootNode 根节点
  • @return 翻转后的树根节点(其实就是原二叉树的根节点)
    */
    + (BinaryTreeNode *)invertBinaryTree:(BinaryTreeNode *)rootNode {
    if (!rootNode) { return nil; }
    if (!rootNode.leftNode && !rootNode.rightNode) { return rootNode; }
    [self invertBinaryTree:rootNode.leftNode];
    [self invertBinaryTree:rootNode.rightNode];
    BinaryTreeNode *tempNode = rootNode.leftNode;
    rootNode.leftNode = rootNode.rightNode;
    rootNode.rightNode = tempNode;
    return rootNode;
    }

pragma mark - 遍历二叉树

/// 先序遍历
+ (void)treeFirstInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger value))block{
if (block) {
block(rootNode.value);
}
if (rootNode.leftNode) {
[self treeFirstInformationWithNode:rootNode.leftNode resultBlock:block];
}
if (rootNode.rightNode) {
[self treeFirstInformationWithNode:rootNode.rightNode resultBlock:block];
}
}

/// 中序遍历
+ (void)treeMiddleInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger value))block{

if (rootNode.leftNode) {
    [self treeMiddleInformationWithNode:rootNode.leftNode resultBlock:block];
}
if (block) {
    block(rootNode.value);
}
if (rootNode.rightNode) {
    [self treeMiddleInformationWithNode:rootNode.rightNode resultBlock:block];
}
}

/// 后序遍历
+ (void)treeLastInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger value))block{
if (rootNode.leftNode) {
[self treeLastInformationWithNode:rootNode.leftNode resultBlock:block];
}

if (rootNode.rightNode) {
    [self treeLastInformationWithNode:rootNode.rightNode resultBlock:block];
}
if (block) {
    block(rootNode.value);
}
}

/// 二叉树深度
+ (NSInteger)depathOfTree:(BinaryTreeNode *)rootNode{
if (!rootNode) return 0;
if (!rootNode.leftNode && !rootNode.rightNode) return 1;
NSInteger leftDepth = [self depathOfTree:rootNode.leftNode];
NSInteger rightDepth = [self depathOfTree:rootNode.rightNode];
return MAX(leftDepth, rightDepth) + 1;
}

/// 二叉树所有节点数 节点数=左子树节点数+右子树节点数+1(根节点)
+ (NSInteger)numberOfNodesInTree:(BinaryTreeNode *)rootNode{
if (!rootNode) return 0;
return [self numberOfNodesInTree:rootNode.leftNode] + [self numberOfNodesInTree:rootNode.rightNode] + 1;
}

//二叉树中某个节点到根节点的路径
+ (NSArray *)pathOfTreeNode:(BinaryTreeNode *)treeNode inTree:(BinaryTreeNode *)rootNode {
NSMutableArray *pathArray = [NSMutableArray array];
[self isFoundTreeNode:treeNode inTree:rootNode routePath:pathArray];
return pathArray;
}

pragma mark - Private SEL

+ (BinaryTreeNode *)addTreeNode:(BinaryTreeNode *)treeNode value:(NSInteger)value {
//根节点不存在,创建节点
if (!treeNode) {
    treeNode = [BinaryTreeNode new];
    treeNode.value = value;
    NSLog(@"node:%@", @(value));
}
else if (value <= treeNode.value) {
    NSLog(@"to left");
    //值小于根节点,则插入到左子树
    treeNode.leftNode = [[self class] addTreeNode:treeNode.leftNode value:value];
}
else {
    NSLog(@"to right");
    //值大于根节点,则插入到右子树
    treeNode.rightNode = [[self class] addTreeNode:treeNode.rightNode value:value];
}
return treeNode;
}

+ (BOOL)isFoundTreeNode:(BinaryTreeNode *)treeNode inTree:(BinaryTreeNode *)rootNode routePath:(NSMutableArray *)path {

if (!rootNode || !treeNode) {
    return NO;
}
//找到节点
if (rootNode == treeNode) {
    [path addObject:rootNode];
    return YES;
}
//压入根节点,进行递归
[path addObject:rootNode];
//先从左子树中查找
BOOL find = [self isFoundTreeNode:treeNode inTree:rootNode.leftNode routePath:path];
//未找到,再从右子树查找
if (!find) {
    find = [self isFoundTreeNode:treeNode inTree:rootNode.rightNode routePath:path];
}
//如果2边都没查找到,则弹出此根节点
if (!find) {
    [path removeLastObject];
}

return find;
}

7.二分查找

+ (NSInteger)binarySearchNoRecursion:(NSArray *)srcArray withDes:(NSNumber *)des{
NSInteger low = 0;
NSInteger high = [srcArray count] - 1;
while (low <= high) {
    NSInteger middle = low + ((high + low)>>1);//中间位置计算,low+ 最高位置减去最低位置,右移一位,相当于除2.也可以用(high+low)/2
    if ([des integerValue] == [srcArray[middle] integerValue]) return middle;
    else if([des integerValue] < [srcArray[middle] integerValue]) high = middle - 1;
    else low = middle + 1;
}
return -1;
}

+ (NSInteger)binarySearchWithRecursion:(NSArray *)srcArray withDes:(NSNumber *)des{
NSInteger low = 0;
NSInteger high = [srcArray count] - 1;
return [self binSearch:srcArray withLow:low withHigh:high withKey:des];
}

+ (NSInteger)binSearch:(NSArray *)srcArray withLow:(NSInteger)low withHigh:(NSInteger)high withKey:(NSNumber *)key{
if (low <= high) {
    NSInteger mid = (low + high)/2;
    if ([key integerValue] == [srcArray[mid] integerValue]) return mid;
    else if([key integerValue] < [srcArray[mid] integerValue]) return [self binSearch:srcArray withLow:low withHigh:(mid - 1) withKey:key];
    else return [self binSearch:srcArray withLow:mid+1 withHigh:high withKey:key];
}else{
    return -1;
}
}

8.归并排序

+ (void)mergearray:(NSMutableArray *)ary withFirst:(NSInteger)first withMid:(NSInteger)mid withLast:(NSInteger)last ResultAry:(NSMutableArray *)temp{
NSInteger i = first, j = mid + 1;
NSInteger m = mid ,n = last;
NSInteger k = 0;

while (i <= m && j <= n) {
    if (ary[i] <= ary[j])  temp[k++] = ary[i++];
    else temp[k++] = ary[j++];
}

while (i <= m) temp[k++] = ary[i++];

while (j <= n) temp[k++] = ary[j++];

for (i = 0; i < k; i++) ary[first + i] = temp[i];
}

+ (void)mergeSort:(NSMutableArray *)ary withFirst:(NSInteger)first withLast:(NSInteger)last ResultAry:(NSMutableArray *)temp{
if (first < last) {
    NSInteger mid = (first + last) / 2;
    [self mergeSort:ary withFirst:first withLast:mid ResultAry:temp]; // 左边有序
    [self mergeSort:ary withFirst:mid + 1 withLast:last ResultAry:temp]; // 右边有序
    [self mergearray:ary withFirst:first withMid:mid withLast:last ResultAry:temp];// 将二个有序数列合并
}
}

+ (NSMutableArray *)mergeSort:(NSMutableArray *)ary withCapacity:(NSInteger)n{
NSMutableArray *p = [NSMutableArray arrayWithCapacity:n];
[self mergeSort:ary withFirst:0 withLast:n-1 ResultAry:p];
return p;
}

9. 汉诺塔

+ (void)move:(NSInteger)N withA:(NSString *)A withB:(NSString *)B withC:(NSString *)C{
if ( N == 1 ) {
    NSLog(@"Move disk %ld from %@ to %@\n",N,A,C);
}else{
    [self move:(N - 1) withA:A withB:C withC:B];
    NSLog(@"Move disk %ld from %@ to %@\n",N,A,C);
    [self move:(N - 1) withA:B withB:A withC:C];
}
}

10. 快速排序

+ (void)quickSortWithArray:(NSMutableArray *)array withLeft:(NSInteger)left andRight:(NSInteger)right{
if (left >= right) return;

NSInteger i = left;
NSInteger j = right;
NSInteger key = [array[left] integerValue];

while (i < j) {
    while (i < j && key <= [array[j] integerValue]) {
        j--;
    }
    array[i] = array[j];
    while (i < j && key >= [array[i] integerValue]) {
        i++;
    }
    array[j] = array[i];
}
array[i] = [NSNumber numberWithInteger:key];

[[self class] quickSortWithArray:array withLeft:left andRight:i - 1];
[[self class] quickSortWithArray:array withLeft:i + 1 andRight:right];
}

11. 冒泡排序

+ (void)bubbleSortWithArray:(NSMutableArray *)array{

for (int i = 0; i < array.count; i++) {
    for (int j = 0; j < array.count - i - 1; j++) {
        if (array[j] < array[j+1]) {
            int temp = [array[j] intValue];
            array[j] = array[j + 1];
            array[j + 1] = [NSNumber numberWithInt:temp];
        }
    }
}
}

12. 希尔排序

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

推荐阅读更多精彩内容