Tencent interview questions: quickly find the middle node of a singly linked list of unknown length

Title: Quickly find the middle node of a singly linked list of unknown length

First analyze, since it is an interview question, there must be common methods and advanced methods, and advanced methods will undoubtedly give you a lot of points!

The common method is very simple: first traverse the singly linked list to determine the length L of the singly linked list. Then start from the head node and loop L/2 times to find the middle node of the singly linked list.

The algorithmic complexity of the ordinary method is: O(L+L/2) = O(3L/2)

The implementation code of the ordinary method:

    #include<stdio.h>
    #include<malloc.h>
    #include<time.h>
    #include<stdlib.h>
    #include<math.h>

	struct node
        {
             int data; //elementtype represents a data type, which may be int/char, etc.
             struct node *next; //next pointer, used for linked list structure to point to the next node
        };

	typedef struct node node; //Redefine the type of struct node to node

    int GetMidNode(node* L); //function declaration
    void List(node* head);
    node* Creat(int Count);
    int Length(node *L);

	intmain()
        {
        node* head;
        int a;
        int Num;

		printf("1.Creat linklist\n2.View linklist\n3.Length of linklist\n4.Value of middle node\n0.Exit\n");
        while(1)
        {
			scanf("%d",&a);
			switch(a)
				{

				case 1:
					printf("Enter the number of linked list nodes:\n");
					scanf("%d",&Num);
					head = Create(Num);
					printf("\n");
					break;
				case 2:
					printf("List:\n");
					List(head);
					printf("\n");
					printf("\n");
					break;
				case 3:
					printf("Length of linklist:\n");
					printf("%d",Length(head));
					printf("\n");
					printf("\n");
					break;
				case 4:
					printf("Value of middle node:\n");
					printf("%d",GetMidNode(head));
					printf("\n");
					printf("\n");
					break;
				case 0:
					return 0;
				}

		}
        return 0;
		}


    node* Creat(int Count) //Create a linked list
    {
        node *p1,*p2,*head;
        int n;
        srand(time(NULL));//Generate seed
        head = p1 = (node*)malloc(sizeof(node));
		head->data = rand()%1000;
        head->next = NULL;
        for (n = 1;n < Count;n++)
            {
                p2 = (node*)malloc(sizeof(node));
                p2->data = rand()%1000;
                p1->next = p2;
                p1 = p2;
            }
        p1->next = NULL;
        return(head);
    }


	void List(node* head) //Print the linked list
        {
            node * p1;
            p1 = head;
            while(p1!= NULL)
            {
                printf("%4d",p1->data);
                p1 = p1->next;
            }
        }


	int GetMidNode(node* L) //find the middle value of the linked list
        {
            int a,i,n;
            n = Length(L); //Get the length of the linked list
			for (i = 1;i < (n+1)/2;i++)
			{
				L = L->next; //find the linked list from the beginning, to half of the linked list
			}
			a = L->data;
			return a;
        }


	int Length(node ​​*L) //Calculate the length of the linked list
        {
			int n = 0;
			while(L->next!= NULL)
			{
				n++;
				L = L->next;
			}
			n++;
			return n;
		}

This code implements 4 functions: 1. Create a linked list 2. View the linked list 3. Calculate the length of the linked list 4. Query the intermediate value of the linked list

In the fourth function we use the normal method, which is the int GetMidNode(node* L) function


=================================================

The advanced method uses the principle of fast and slow pointers: set the two pointers *search and *mid to both point to the head node of the singly linked list. Where *search moves twice as fast as *mid. When *search points to the end node, *mid is right in the middle. That is, the idea of ​​a ruler.

The algorithmic complexity of the advanced method is: O(L/2)

Advanced method implementation code:

    #include<stdio.h>
    #include<malloc.h>
    #include<time.h>
    #include<stdlib.h>
    #include<math.h>

	struct node
        {
             int data; //elementtype represents a data type, which may be int/char, etc.
             struct node *next; //next pointer, used for linked list structure to point to the next node
        };

	typedef struct node node; //Redefine the type of struct node to node

    int GetMidNode(node* L); //function declaration
    void List(node* head);
    node* Creat(int Count);
    int Length(node *L);

	intmain()
        {
        node* head;
        int a;
        int Num;

		printf("1.Creat linklist\n2.View linklist\n3.Length of linklist\n4.Value of middle node\n0.Exit\n");
        while(1)
        {
			scanf("%d",&a);
			switch(a)
				{

				case 1:
					printf("Enter the number of linked list nodes:\n");
					scanf("%d",&Num);
					head = Create(Num);
					printf("\n");
					break;
				case 2:
					printf("List:\n");
					List(head);
					printf("\n");
					printf("\n");
					break;
				case 3:
					printf("Length of linklist:\n");
					printf("%d",Length(head));
					printf("\n");
					printf("\n");
					break;
				case 4:
					printf("Value of middle node:\n");
					printf("%d",GetMidNode(head));
					printf("\n");
					printf("\n");
					break;
				case 0:
					return 0;
				}

		}
        return 0;
		}


    node* Creat(int Count) //Create a linked list
    {
        node *p1,*p2,*head;
        int n;
        srand(time(NULL));//Generate seed
        head = p1 = (node*)malloc(sizeof(node));
		head->data = rand()%1000;
        head->next = NULL;
        for (n = 1;n < Count;n++)
            {
                p2 = (node*)malloc(sizeof(node));
                p2->data = rand()%1000;
                p1->next = p2;
                p1 = p2;
            }
        p1->next = NULL;
        return(head);
    }


	void List(node* head) //Print the linked list
        {
            node * p1;
            p1 = head;
            while(p1!= NULL)
            {
                printf("%4d",p1->data);
                p1 = p1->next;
            }
        }


	int GetMidNode(node* L) //find the middle value of the linked list
        {
            int a;
            node *search,*mid;
            mid = search = L;
            while(search->next != NULL)
            {
                if(search->next->next != NULL)
					{
						search = search->next->next;
						mid= mid->next;
					}
                else
					{
						search = search->next;
					}
            }
            a = mid->data;
            return a;
        }


	int Length(node ​​*L) //Calculate the length of the linked list
        {
			int n = 0;
			while(L->next!= NULL)
			{
				n++;
				L = L->next;
			}
			n++;
			return n;
		}

The difference from the previous code is that the implementation of the int GetMidNode(node* L) function uses the principle of fast and slow pointers. When the fast pointer traverses the list, the slow pointer is exactly halfway down the list.

Results show:

  


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325933460&siteId=291194637