zoukankan      html  css  js  c++  java
  • 关于链表的练习

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    
    /*一般来说写题目不要因为一个题目编写过多的函数(》=2)。写这么多面试官会觉得你很蠢……,除非是大编程题*/
    struct Node{
        int data;
        Node* next;
    };
    
    Node* CreateList(int val[],int n)
    {
        Node* head = (Node*)malloc(sizeof(Node));
        head->next = NULL;
    
        Node* p = head;
        for (int i = 0; i < n;i++)
        {
            Node* new_node = (Node*)malloc(sizeof(Node));
            new_node->data = val[i];
            new_node->next = NULL;
            p->next = new_node;
            p = new_node;
        }
        return head;
    }
    
    Node* CreateCirList(int val[], int n, int start)
    {
        Node* head = (Node*)malloc(sizeof(Node));
        head->next = NULL;
    
        Node* p = head;
        Node* p_in;
        for (int i = 0; i < n; i++)
        {
            Node* new_node = (Node*)malloc(sizeof(Node));
            new_node->data = val[i];
            new_node->next = NULL;
            if (start == i)
            {
                p_in = new_node;
            }
            p->next = new_node;
            p = new_node;
        }
        p->next = p_in;
        return head;
    }
    
    /*1. 求单链表中结点的个数*/
    int NodeNum(Node* head)
    {
        int i = 0;
        Node* p = head;
        if (p == NULL)
        {
            return 0;
        }
        while (p->next != NULL)
        {
            i++;
            p = p->next;
        }
        return i;
    }
    /*2. 将单链表反转*/
    Node* Reverse(Node* head)
    {
        if (head == NULL || head->next == NULL)
        {
            return head;//Empty
        }
        Node* pre, *cur=head->next, *nxt;
        pre = nxt = NULL;
        while (cur)//每次循环:调整前面两个指针指向。另外把三个指针都依次向后移动一位。
        {
            nxt = cur->next;
            cur->next = pre;
            pre = cur;
            cur = nxt;
        }
        head->next = pre;
        return head;
    }
    /*MTK程序填空题*/
    Node* Reverse_MTK(Node* head)
    {
        if (head == NULL || head->next == NULL)
        {
            return head;//Empty
        }
        Node* pre=head, *cur = pre->next, *nxt=cur->next;
        /*blank*/
        pre->next = NULL;
        while (nxt != NULL)
        {
            cur->next = pre;
            pre = cur;
            cur = nxt;
            /*blank*/
            nxt = cur->next;
        }
        /*blank*/
        cur->next = pre;
        head->next = cur;//MTK原题为head=cur。我修改为这个是因为head-》next=cur是针对有头的链表。
        return head;
    }
    /*3. 查找单链表中的倒数第K个结点(k > 0)*/
    //可以知道总节点个数然后遍历。也可以用两个相隔一定距离的指针
    Node* GetBackNode(Node* head,int k)
    {
        Node* first = head;
        Node* second = head;
        while (k--)
        {
            if (second==NULL)
            {
                printf("No such Node!
    ");
                return head;
            }
            second = second->next;
        }
        /*此时first和second保持k距离*/
        while (second != NULL)
        {
            first = first->next;
            second = second->next;
        }
        return first;
    }
    /*4. 查找单链表的中间结点*/
    /*两个办法,一个知道数量就不说了。另一个两个指针,一个走两个一个走一个,两个的走到头,一个的就是中间位置*/
    Node* GetMidNode(Node* head)
    {
        Node* first = head, *second = head;
        if (head == NULL || head->next == NULL || head->next->next == NULL)
        {
            return head;
        }
        while (first != NULL)
        {
            second = second->next;
            first = first->next;
            if (first != NULL)
            {
                first = first->next;
            }
            else
            {
                return second;
            }
        }
        return second;
    }
    /*5. 从尾到头打印单链表*/
    /*用栈,我想到了但是然并卵没什么用。先写进数组,不过这样用链表干嘛呢?看了别人想法,递归是很好的选择*/
    void BackPrint(Node* t)
    {//注意下:输入为head,第一个元素是head-》next。
        if (t->next == NULL)
        {
            return;//只返回一次
        }
        else
        {
            BackPrint(t->next);
            printf("%d
    ", t->next->data);//最后一个输出肯定是head-》next的值
        }
    }
    /*6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序*/
    Node* MergeSortedList(Node* pHead1, Node* pHead2)
    {
        if (pHead1 == NULL || pHead1->next == NULL)
        {
            return pHead2;
        }
        if (pHead2 == NULL || pHead2->next == NULL)
        {
            return pHead1;
        }
        Node* p1 = pHead1->next, *p2 = pHead2->next;
        Node* new_head = (Node*)malloc(sizeof(Node));new_head->next = NULL;
        Node* tmp = new_head;
        if (p1->data <= p2->data)
        {
            tmp->next = p1;
            p1 = p1->next;
        }
        else
        {
            tmp->next = p2;
            p2 = p2->next;
        }
        tmp = tmp->next;
        while (p1!=NULL && p2!=NULL)
        {
            if (p1->data <= p2->data)
            {
                tmp->next = p1;
                p1 = p1->next;
            }
            else
            {
                tmp->next = p2;
                p2 = p2->next;
            }
            tmp = tmp->next;
        }
        if (p1 != NULL)
        {
            tmp->next = p1;
        }
        if (p2 != NULL)
        {
            tmp->next = p2;
        }
        return new_head;
    }
    /*7. 判断一个单链表中是否有环*/
    int HaveCircle(Node* head)
    {
        Node* fast = head, *slow = head;
        while (fast != NULL && slow != NULL)
        {
            fast = fast->next;
            if (fast != NULL)
            {
                fast = fast->next;
            }
            else
            {
                printf("The List has no circle!
    ");
                return 0;
            }
            slow = slow->next;
            if (slow == fast)
            {
                printf("The List has at least a circle!
    ");
                return 1;
            }
        }
        return 0;
    }
    /*8. 判断两个单链表是否相交*/
    int IsCross(Node* head1, Node* head2)
    {
        Node* p1 = head1, *p2 = head2;
        while (p1->next != NULL)
        {
            p1 = p1->next;
        }
        while (p2->next != NULL)
        {
            p2 = p2->next;
        }
        if (p1 == p2)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    /*9. 求两个单链表相交的第一个节点*/
    Node* GetFirstNode(Node* head1, Node* head2)
    {
        Node* p1 = head1->next, *p2 = head2->next;
        int len1 = 0, len2 = 0;
        while (p1 != NULL)
        {
            len1++;
            p1 = p1->next;
        }
        while (p2!=NULL)
        {
            len2++;
            p2 = p2->next;
        }
        if (len1 >= len2)
        {
            while (len1 - len2)
            {
                p1 = p1->next;
            }
        }
        else
        {
            while (len2 - len1)
            {
                p2 = p2->next;
            }
        }
        while (p1 != p2)
        {
            p1 = p1->next;
            p2 = p2->next;
        }
        return p1;
    }
    
    int main()
    {
        int mat1[8] = { 1, 2, 3, 4, 5, 6 };
        int mat2[8] = { 3, 5, 7, 8, 9, 10 };
        Node* head1 = CreateList(mat1, 6);
        Node* head2 = CreateList(mat2, 6);
        Node* head_cir = CreateCirList(mat1, 6, 3);
        HaveCircle(head_cir);
        HaveCircle(head1);
    
        printf("The number of List is %d
    ", NodeNum(head1));
    
        //Reverse_MTK(head);
        BackPrint(head1);
    
        Node* a=MergeSortedList(head1, head2);
    
    
        return 0;
    }

    关于链表的环长,环起点等换在另一篇来写。

  • 相关阅读:
    .NET CF 枚举设备窗口
    .NET CF WM设备(手机)振动
    如何将 byte[] 转换为 IntPtr?
    Mobile 重启设备
    如何删除只读文件?
    随笔
    故乡的原风景
    岁月神偷
    opengl纹理映射
    bootstrap 学习笔记
  • 原文地址:https://www.cnblogs.com/wyc199288/p/5188465.html
Copyright © 2011-2022 走看看