剑指offer第五天

面试题16 反转链表

思路 当我们调整节点i的next指针时,需要知道i的前一个节点,当i的next指向前一节点时,我们就无法找到i的下一个节点,所以我们还需要保存i的下一个节点。
代码

struct node * reverseList(struct node *head){
  struct node *p,*pre,*next,*reverseHead = NULL;
  pre=NULL;
  p=head;
  //如果链表只有一个节点 直接返回
  if (p->next==NULL) {
    return p;
  }

  while (p!=NULL) {
    next=p->next;
    //如果p是尾节点 那么p就是反转过后的头节点
    if (next==NULL) {
        reverseHead=p;
    }
    p->next=pre;
    pre=p;
    p=next;
}
return reverseHead;
}

递归代码

//递归反转链表
void DiguireverseList(struct node *pre,struct node *p,struct node *next){
    next=p->next;
//如果下一个节点为空 那么尾节点指向前一个节点 并且设置反转过后的头节点为p
    if (next==NULL) {
        p->next=pre;
        DiguireverseHead=p;
        //否则 p指向前一个节点 并移动pre,p递归调用函数
    }else{
        p->next=pre;
        pre=p;
        p=next;
        DiguireverseList(pre, p, next);
    }
   }

面试题17 合并两个排序的链表

输入两个递增的链表,合并两个链表使其仍然递增。
思路 比较两个链表的头节点,较小的加入新链表。下一步和上一步相同,递归完成这个过程。
代码

#pragma mark-合并两个递增链表
struct node * merge(struct node *p1,struct node *p2){
if (p1==NULL) {
    return p2;
}
if (p2==NULL) {
    return p1;
}
struct node *mergeNode=NULL;
if (p1->datadata) {
    mergeNode=p1;
    mergeNode->next=merge(p1->next, p2);
}else{
    mergeNode=p2;
    mergeNode->next=merge(p1, p2->next);
}
return mergeNode;
}

面试题18 树的子结构

输入两颗二叉树a和b 判断b是不是a的子结构
思路 首先,遍历a 看a中有没有节点和b的根节点值相等,若有,遍历b看和a是否相同,直到b遍历完
代码

int DoseTree1hasTree2(struct BinaryTreeNode *p1,struct BinaryTreeNode *p2){
if (p2==NULL) {
    return 1;
}
if (p1==NULL) {
    return 0;
}
if (p1->value!=p2->value) {
    return 0;
}
return DoseTree1hasTree2(p1->leftchild, p2->leftchild)&&DoseTree1hasTree2(p1->rightchild, p2->rightchild);
}
int isSubtree(struct BinaryTreeNode *p1,struct BinaryTreeNode *p2){
int result=0;
//首先判断a树中有没有b树的根节点
if (p1 != NULL && p2 != NULL) {
    if (p1->value==p2->value) {
        result=DoseTree1hasTree2(p1, p2);
    }
    //向左子树找
    if (!result) {
        result=isSubtree(p1->leftchild, p2);
    }
     //向右子树找
    if (!result) {
        result=isSubtree(p1->rightchild, p2);
    }

}
return result;
}

面试题19 二叉树的镜像

思路 遍历二叉树,每到一个节点,若他是叶子节点,结束.若不是,交换他的左右节点。
代码

void mirror(struct BinaryTreeNode *p){
if (p->leftchild==NULL && p->rightchild==NULL) {
    return;
}
struct BinaryTreeNode *t=p->leftchild;
p->leftchild=p->rightchild;
p->rightchild=t;
if (p->leftchild) {
    mirror(p->leftchild);
}
if (p->rightchild) {
    mirror(p->rightchild);
}
}

面试题20 顺时针打印矩阵

按从里向外以顺时针的顺序依次打印出每一个数字。
将问题分解为两个问题 打印几圈 每一圈如何打印
代码

//打印一圈
void printCircle(int **numbers,int col,int row,int start){
int endx=col-1-start;
int endy=row-1-start;
int i=0;
//从左向右打
for (i=start; i<=endx; i++) {
    printf("%d",numbers[start][i]);
}
//从上往下打 endy要大于start
if (start=start; i--) {
        printf("%d",numbers[endy][i]);
    }
}
//从下往上打 至少两行三列
if (start=start+1; i--) {
        printf("%d",numbers[i][start]);
    }
}
}
void Printclock(int **numbers,int col,int row){
int start=0;
while (col>start*2&&row>start*2) {
    printCircle(numbers,col,row,start);
    ++start;
}
}

你可能感兴趣的:(剑指offer第五天)