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

本文详细介绍了单链表的基本操作,包括如何仅遍历一次找到中间节点、在不同位置插入新节点、反转链表等,并提供了完整的C语言实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

给出一个单链表,不知道结点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;
}

运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值