问题10:还是单链表的一些问题(如单链表,怎样只遍历一次就可以求出中间结点)

来源:互联网 发布:腾讯算法工程师待遇 编辑:程序博客网 时间:2024/05/16 15:56

问题描述:

给出一个单链表,不知道结点N的值,怎样只遍历一次就可以求出中间结点?

/* *该题的大致思路是设置两个指针,比如*p1,*p2。p2每次移动两个位置,而p1每次移动一个位置。当p2移动到最后时,p1就是中间结点了。 */node *searchMid(node *head){   if(NULL == head)      return head;   if(NULL == head->next)      return head->next;   node *p1, *p2;   P1 = P2 = head;   while(p2->next!= NULL)   {      /*p2结点移动2个结点位置*/      P2 = P2->next;      if(p2->next != NULL)      p2 = p2->next;  p1 = p1->next;   }   return p1;}


单链表插入结点

       关于单链表插入结点,大体要注意三种情况:

一是在第一个结点前插入;

二是在链表的中间插入;

三是在链表的最后插入。

另外还需要注意单链表没有指向前驱结点的指针,所以在实际程序中往往需要记录前驱结点,相信只要知道了这几点写出相应的代码就不太困难了。

代码如下:

#include <stdio.h>#include <malloc.h>typedef struct student{   int data;   struct student *next;}node;//创建链表node *creat(){   node *head, *p, *s;   int x, cycle = 1;   head = (node *)malloc(sizeof(node));   p = head;   while(cycle)   {      printf("\nplease enter the data:");      scanf("%d", &x);  if(x != 0)  {     s = (node *)malloc(sizeof(node));     s->data = x;     printf("\n%d", s->data);     p->next = s;     p = s;  }  else     cycle = 0;   }   head = head->next;   printf("\nThe value of the first node is:%d\n", head->data);   p->next = NULL;   return head;}//单链表插入结点node *insert_to_list(node *head, int num){   node *cur, *pre, *s;   cur = head;   s = (node *)malloc(sizeof(node));   s->data = num;   while(s->data > cur->data && cur->next != NULL)   {      pre = cur;  cur = cur->next;   }   if(s->data <= cur->data)   {      if(cur == head)  {      s->next = head;  head = s;  }  else  {     s->next = cur; pre->next = s;  }   }   else   {      cur->next = s;  s->next = NULL;   }      return head;}//单链表测长  int length(node *head)  {     int len = 0;     node *p = head;     while(p != NULL)     {         len++;       p = p->next;     }     return len;  } //单链表打印  void print(node *head)  {    node *p = head;    int n = length(head);    printf("\nNow, These %d records are:\n", n);    while(p != NULL)    {       printf("\n     uuu  %d    ", p->data);       p = p->next;    }  }int main(void){   //creat a list   node *List = creat();   print(List);   node *p = insert_to_list(List, 5);   print(p);   return 0;}

运行结果:



编程实现单链表的逆置

代码如下:

#include <stdio.h>#include <malloc.h>typedef struct student{   int data;   struct student *next;}node;//创建链表node *creat(){   node *head, *p, *s;   int x, cycle = 1;   head = (node *)malloc(sizeof(node));   p = head;   while(cycle)   {      printf("\nplease enter the data:");      scanf("%d", &x);  if(x != 0)  {     s = (node *)malloc(sizeof(node));     s->data = x;     printf("\n%d", s->data);     p->next = s;     p = s;  }  else     cycle = 0;   }   head = head->next;   printf("\nThe value of the first node is:%d\n", head->data);   p->next = NULL;   return head;}//单链表插入结点node *insert_to_list(node *head, int num){   node *cur, *pre, *s;   cur = head;   s = (node *)malloc(sizeof(node));   s->data = num;   while(s->data > cur->data && cur->next != NULL)   {      pre = cur;  cur = cur->next;   }   if(s->data <= cur->data)   {      if(cur == head)  {      s->next = head;  head = s;  }  else  {     s->next = cur; pre->next = s;  }   }   else   {      cur->next = s;  s->next = NULL;   }      return head;}//单链表测长  int length(node *head)  {     int len = 0;     node *p = head;     while(p != NULL)     {         len++;       p = p->next;     }     return len;  } //单链表打印  void print(node *head)  {    node *p = head;    int n = length(head);    printf("\nNow, These %d records are:\n", n);    while(p != NULL)    {       printf("\n     uuu  %d    ", p->data);       p = p->next;    }  }//实现单链表的逆置node *reverse(node *head){   node *p1, *p2, *p3;   if(head == NULL || head->next == NULL)      return head;   p1 = head;   p2 = head->next;   while(p2)   {  p3 = p2->next;  p2->next = p1;  p1 = p2;  p2 = p3;   }   head->next = NULL;   head = p1;   return head;}int main(void){   //creat a list   node *List = creat();   print(List);   node *p = insert_to_list(List, 5);   print(p);   p = reverse(p);   print(p);   return 0;}

运行结果: