zoukankan      html  css  js  c++  java
  • leetcode链表题

    链表:

    • 倒序输出链表
    • 链表的倒数第k个节点
    • 合并两个排序的链表

    倒序输出链表

    两种思路:

    1.利用栈:遍历链表,将链表元素添加的栈中,遍历结束后,从栈顶依次取出元素即可。

    2.利用链表:新建一个新链表,遍历旧链表,将元素插入新链表的头指针后面,遍历结束,遍历新链表即可。

    这里利用都是栈先进后出的特性,利用数组+头指针构建栈,需要解决扩容问题,利用链表就没有这个问题,但需要更多的内存空间存储节点指针。

    #include <stdio.h>
    #include<malloc.h>
    
    //声明链表节点类型
    typedef struct LISTtag LISTtagNode;
    struct    LISTtag{
        int value;
        LISTtagNode *next;
    };
    
    #define M 8
    typedef struct stall Stall;
    struct stall{
        int ele[M];
        int top;
    };
    
    
    
    //创建链表
    LISTtagNode * create(){
        LISTtagNode *head;
        head = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        head->next =  NULL;
        return head;
    }
    
    //在链表尾新增节点
    int LinKListInsertbottom(LISTtagNode *head,int value){
        if(head == NULL){
            return -1;
        }
        //新建节点
        LISTtagNode *node;
        node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        //节点赋值,此节点为最后一个节点
        node->value = value;
        node->next = NULL;
        LISTtagNode *t = head;
        //找到尾指针
        while (t->next != NULL) {
            t = t->next;
        }
        t->next= node;
         return 1;
    }
    
    //在链表尾新增节点
    int LinKListInserttop(LISTtagNode *head,int value){
        if(head == NULL){
            return -1;
        }
        //新建节点
        LISTtagNode *node;
        node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        //节点赋值,此节点为最后一个节点
        node->value = value;
        node->next = head->next;
        head->next = node;
        return 1;
    }
    
    //打印链表
    int PrindLinKList(LISTtagNode *head){
         if(head == NULL){
            return -1;
        }
        LISTtagNode *t = head;
        while (t->next != NULL) {
            t = t->next;
            printf("%d ", t->value);
        }
        return 1;
    }
    
    //修改某个位置的值
    int update(LISTtagNode *head,int index,int value){
         if(head == NULL){
            return -1;
        }
        LISTtagNode *t = head;
        int i = 0;
        //要么是最后一个节点,要么超出index
        while ((t->next != NULL)&&(i<index)) {
            t = t->next;
            i++;
        }
        //1.t->next ==NULL,退出循环,i<index不满足情况
        //2.i>=index,退出循环,t->next != NULL不满足情况
        //3.上面两种情况同时发生
        //如果为最后一个节点或者超出index才会执行下列语句
        if(i == index && i != 0 ){//i != 0,头节点没有存储数据
            t->value = value;
        }
        return 1;
    }
    
    
    int PrindLinKListreverse1(LISTtagNode *head,Stall *stall1){
        if(head == NULL){
            return -1;
        }
        LISTtagNode *node = head;
        while(node->next != NULL){
            node = node->next;
            addone(stall1,node->value);
        }
       topall(stall1);
       return 1;
    }
    
    
    void addone(Stall *stall1,int value){
        if((stall1->top)<M){
            stall1->ele[stall1->top] = value;
            stall1->top ++;
        }
    }
    
    void topall(Stall *stall1){
        stall1->top --;
        printf("
    栈(数组+头指针)反序打印链表:");
        while((stall1->top)>=0){
            printf("%d ",stall1->ele[stall1->top]);
            stall1->top --;
        }
    }
    
    
    int PrindLinKListreverse2(LISTtagNode *head){
        if(head == NULL){
            return -1;
        }
        LISTtagNode *node = head;
        LISTtagNode *newhead = create();
        while(node->next != NULL){
            node = node->next;
            LinKListInserttop(newhead,node->value);
        }
        printf("
    链表头插法反序打印链表:");
        PrindLinKList(newhead);
        return 1;
    }
    
    int main () {
        LISTtagNode *head = create();
       
        LinKListInsertbottom(head,7);
        LinKListInsertbottom(head,22);
        LinKListInsertbottom(head,3);
        LinKListInsertbottom(head,43);
        LinKListInsertbottom(head,32);
        LinKListInsertbottom(head,42);
        LinKListInsertbottom(head,12);
        LinKListInsertbottom(head,14);
        LinKListInsertbottom(head,14);
        printf("
    正序打印链表:");
        PrindLinKList(head);
        //利用数组+头指针构建栈,反序链表,先进后出
        Stall *stall1;
        stall1 = (Stall*)malloc(sizeof(Stall));
        stall1->top = 0;
        PrindLinKListreverse1(head,stall1);
    
        //利用链表头插法,新建一个链表,在头部插入解决另一个链表的反序输出
        PrindLinKListreverse2(head);
        
        return 0;
    }

    链表的倒数第k个节点

    思路:

    我们可以定义两个指针。第一个指针从链表的头指针开始遍历向前走k-1,第二个指针保持不动;从第k步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点。

    效果示意图,以链表总共6个结点,求倒数第3个结点为例:

    #include <stdio.h>
    #include<malloc.h>
    
    //声明链表节点类型
    typedef struct LISTtag LISTtagNode;
    struct    LISTtag{
        int value;
        LISTtagNode *next;
    };
    
    //创建链表
    LISTtagNode * create(){
        LISTtagNode *head;
        head = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        head->next =  NULL;
        return head;
    }
    
    //在链表尾新增节点
    int LinKListInsertbottom(LISTtagNode *head,int value){
        if(head == NULL){
            return -1;
        }
        //新建节点
        LISTtagNode *node;
        node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        //节点赋值,此节点为最后一个节点
        node->value = value;
        node->next = NULL;
        LISTtagNode *t = head;
        //找到尾指针
        while (t->next != NULL) {
            t = t->next;
        }
        t->next= node;
         return 1;
    }
    
    //在链表头新增节点
    int LinKListInserttop(LISTtagNode *head,int value){
        if(head == NULL){
            return -1;
        }
        //新建节点
        LISTtagNode *node;
        node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        //节点赋值,此节点跟在头节点后
        node->value = value;
        node->next = head->next;
        head->next = node;
        return 1;
    }
    
    //打印链表
    int PrindLinKList(LISTtagNode *head){
         if(head == NULL){
            return -1;
        }
        LISTtagNode *t = head;
        while (t->next != NULL) {
            t = t->next;
            printf("%d ", t->value);
        }
        return 1;
    }
    
    //修改某个位置的值
    int update(LISTtagNode *head,int index,int value){
         if(head == NULL){
            return -1;
        }
        LISTtagNode *t = head;
        int i = 0;
        //要么是最后一个节点,要么超出index
        while ((t->next != NULL)&&(i<index)) {
            t = t->next;
            i++;
        }
        //1.t->next ==NULL,退出循环,i<index不满足情况
        //2.i>=index,退出循环,t->next != NULL不满足情况
        //3.上面两种情况同时发生
        //如果为最后一个节点或者超出index才会执行下列语句
        if(i == index && i != 0 ){//i != 0,头节点没有存储数据
            t->value = value;
        }
        return 1;
    }
    
    LISTtagNode * printindex(LISTtagNode *head,int index){
        int i = 0;
        LISTtagNode *t1 = head;
        while((t1->next!=NULL)&&(i<index)){
            t1 = t1->next;
            i++;
        }
        if(i==index){
            LISTtagNode *t2 = head;
            while((t1->next!=NULL)){
                t1 = t1->next;
                t2 = t2->next;
            }
            printf("
    %d ",t2->value);
            return t2;
        }
        return NULL;
    }
    
    
    int main () {
        LISTtagNode *head = create();
       
        LinKListInsertbottom(head,7);
        LinKListInserttop(head,22);
        LinKListInsertbottom(head,3);
        LinKListInsertbottom(head,43);
        LinKListInsertbottom(head,32);
        LinKListInsertbottom(head,42);
        LinKListInsertbottom(head,12);
        LinKListInsertbottom(head,14);
        LinKListInsertbottom(head,14);
        printf("
    正序打印链表:");
        PrindLinKList(head);
        printindex(head,3);
        return 0;
    }

    合并两个排序的链表

    思路:

    合并两个递增的链表。

    需要新建一个新链表,因为两个旧链表已经完成排序,我们需要比较两个旧链表的元素,每次选取比较中更小的元素插入新链表,这里需要移动指针,已经插入的需要往后移,没有插入的不动即可,最后可能有一个旧链表多出来一些元素,将这个旧链表剩下的元素插入新链表中即可。

    #include <stdio.h>
    #include<malloc.h>
    
    //声明链表节点类型
    typedef struct LISTtag LISTtagNode;
    struct    LISTtag{
        int value;
        LISTtagNode *next;
    };
    
    //创建链表
    LISTtagNode * create(){
        LISTtagNode *head;
        head = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        head->next =  NULL;
        return head;
    }
    
    //在链表尾新增节点
    int LinKListInsertbottom(LISTtagNode *head,int value){
        if(head == NULL){
            return -1;
        }
        //新建节点
        LISTtagNode *node;
        node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        //节点赋值,此节点为最后一个节点
        node->value = value;
        node->next = NULL;
        LISTtagNode *t = head;
        //找到尾指针
        while (t->next != NULL) {
            t = t->next;
        }
        t->next= node;
         return 1;
    }
    
    //在链表头新增节点
    int LinKListInserttop(LISTtagNode *head,int value){
        if(head == NULL){
            return -1;
        }
        //新建节点
        LISTtagNode *node;
        node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        //节点赋值,此节点跟在头节点后
        node->value = value;
        node->next = head->next;
        head->next = node;
        return 1;
    }
    
    //打印链表
    int PrindLinKList(LISTtagNode *head){
         if(head == NULL){
            return -1;
        }
        LISTtagNode *t = head;
        while (t->next != NULL) {
            t = t->next;
            printf("%d ", t->value);
        }
        return 1;
    }
    
    //修改某个位置的值
    int update(LISTtagNode *head,int index,int value){
         if(head == NULL){
            return -1;
        }
        LISTtagNode *t = head;
        int i = 0;
        //要么是最后一个节点,要么超出index
        while ((t->next != NULL)&&(i<index)) {
            t = t->next;
            i++;
        }
        //1.t->next ==NULL,退出循环,i<index不满足情况
        //2.i>=index,退出循环,t->next != NULL不满足情况
        //3.上面两种情况同时发生
        //如果为最后一个节点或者超出index才会执行下列语句
        if(i == index && i != 0 ){//i != 0,头节点没有存储数据
            t->value = value;
        }
        return 1;
    }
    
    //修改某个位置的值
    int sort(LISTtagNode *head1,LISTtagNode *head2){
        if(head1 == NULL|| head2 == NULL ){
            return -1;
        }
        LISTtagNode *newhead = create();
        LISTtagNode *t1 = head1->next;
        LISTtagNode *t2 = head2->next;
        //如果两个链表其中有一个链表的节点为NULL,则退出循环
        while((t1!= NULL)&&(t2!= NULL)){
            if(t1->value<=t2->value){
                LinKListInsertbottom(newhead,t1->value);
                t1 = t1->next;
            }else{
                LinKListInsertbottom(newhead,t2->value);
                t2 = t2->next;
            }        
        }
        if(t1 == NULL){
            while(t2 !=NULL){
                LinKListInsertbottom(newhead,t2->value);
                t2 = t2->next;
            } 
        }else{
            while(t1 !=NULL){
                LinKListInsertbottom(newhead,t1->value);
                t1 = t1->next;
            } 
        }
        printf("
    合并打印链表:");
        PrindLinKList(newhead);
        return 1;
    }
    
    
    int main () {
        LISTtagNode *head1 = create();
        LISTtagNode *head2 = create();
        LinKListInsertbottom(head1,7);
        LinKListInserttop(head1,9);
        LinKListInsertbottom(head1,23);
        LinKListInsertbottom(head1,43);
        LinKListInsertbottom(head1,45);
        LinKListInsertbottom(head1,65);
        printf("
    正序打印链表:");
        PrindLinKList(head1);
        
        LinKListInsertbottom(head2,2);
        LinKListInserttop(head2,3);
        LinKListInsertbottom(head2,4);
        LinKListInsertbottom(head2,9);
        LinKListInsertbottom(head2,32);
        LinKListInsertbottom(head2,34);
        printf("
    正序打印链表:");
        PrindLinKList(head2);
        sort(head1,head2);
        return 0;
    }
  • 相关阅读:
    phpstorm 使用 Xdebug 调试代码
    frp 实现内网穿透(Windows 版)
    update-alternatives 使用详解
    Linux 虚拟机使用 xshell 连接 (debian、kali、CentOS)
    PHP xml 转数组 数组转 xml 操作
    Mac上查看当前安卓手机上打开的app的包名和主程序入口
    启动appium server时打印日志时间
    App自动化测试框架学习探索--从零开始设计
    System.getProperty("user.dir")获取的到底是什么路径?
    读取Excel文件,抛出类似Cleaning up unclosed ZipFile for archive D:projectmyTestautoAppUIexcelMode用例模板2.xlsx 错误解决
  • 原文地址:https://www.cnblogs.com/-wenli/p/12518170.html
Copyright © 2011-2022 走看看