C语言每日一练(二)

这篇具有很好参考价值的文章主要介绍了C语言每日一练(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

单链表经典算法专题

一、 单链表相关经典算法OJ题1:移除链表元素

C语言每日一练(二),c语言,开发语言,java,python
解法一:在原链表中删除Node.next=next的节点
typedef  struct ListNode ListNode;
struct ListNode* removeElements( ListNode* head, int val) {
	ListNode* pcur = head;
	ListNode* pre = head;

	while (pcur)
	{
		while (pcur->val != val )
		{
			pre = pcur;
			pcur = pcur->next;
			if (pcur == NULL)
			{
				return head;
			}
		}
		if (head->val == val)
		{
			head = head->next;
			pcur = head;
			pre = head;
		}
		else if (pcur->val == val)
		{
			pcur = pcur->next;
			pre->next = pcur;
		}
	}

	return head;
}
注意:当头节点的val==val时,要改变头节点的位置
解法二:创建新的指向头尾的链表
typedef  struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val){
     ListNode * newHead=NULL;
     ListNode * newTail=NULL;
     ListNode* pcur=head;
     while(pcur)
     {
         if(pcur->val!=val)
         {
             if(newHead==NULL)
             {
                 newHead=pcur;//注意这里不能写head
                 newTail=pcur;
             }
             else 
             {
                 newTail->next=pcur;
                 newTail=newTail->next;
             }
            
         }
        
         
         pcur=pcur->next;
     }
     if(newTail)
     {
         newTail->next=NULL;
     }
     return newHead;

}
C语言每日一练(二),c语言,开发语言,java,python
注意:这里如果写head的话,当一个节点是要删除的节点,头节点还是那个删除的节点。

二、单链表相关经典算法OJ题2:反转链表

C语言每日一练(二),c语言,开发语言,java,python
解法一:创建新链表,对新链表进行头插
typedef struct ListNode SLNode;
struct ListNode* reverseList(struct ListNode* head){
   SLNode* newHead = NULL;
	SLNode* newTail = NULL;
	SLNode* pcur = head;
	SLNode* last = head;


	while (head!=NULL)
	{
	
		if (newHead == NULL)
		{
			newHead = newTail = head;
			
			
			head = head->next;
		}
		else
		{
			last = head;
			
			
			head = head->next;
			pcur = last;
			pcur->next = newHead;
			newHead = pcur;
		}
		
	}
  if (newTail!=NULL)
  {
      	newTail->next = NULL;
  }
	return newHead;




}
    

解法二:定义三个变量,n1,n2,n3(n1,n2用来反转指向,n3在前面遍历)

typedef  struct ListNode ListNode;
struct ListNode* reverseList( ListNode* head) {
	if(head==NULL)
    {
        return NULL;
    }
        ListNode * n1=NULL;
	ListNode * n2=head;
	ListNode * n3=head->next;
   
    while(n2)
    {
         n2->next=n1;
        n1=n2;
        n2=n3;
        if(n3)
      {
            n3=n3->next;
      }
       
    }
   
    return n1;
}

三、 单链表相关经典算法OJ题3:合并两个有序链表

C语言每日一练(二),c语言,开发语言,java,python
解法一:在原链表基础上进行修改,会使用到指定位置之前插入数
 typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
if (list1 == NULL)
	{
		return list2;
	}
	if (list2 == NULL)
	{
		return list1;
	}
	ListNode* pcur1 = list1;
	ListNode* pre =list1;

	ListNode* pcur2 = list2;
	ListNode* pcur3 = list2->next;
	while (pcur1 && pcur2)
	{
		while (pcur1->val < pcur2->val)
		{
			pre = pcur1;
			pcur1 = pcur1->next;
			if (pcur1 == NULL)
			{
				pre->next = pcur2;
				return list1;
			}
		}
		if (list1->val > pcur2->val)
		{
			pcur2->next = list1;
			list1 = pcur2;
			pre = list1;
			pcur2 = pcur3;
			if (pcur3 != NULL)
			{
				pcur3 = pcur3->next;
			}
		}
		//在pur1实现头插
		else
		{
			pre->next = pcur2;
			pcur2->next = pcur1;
			pcur2 = pcur3;
			if (pcur3 != NULL)
			{
				pcur3 = pcur3->next;
			}
		}

	}
	return list1;
}

 输出结果:

C语言每日一练(二),c语言,开发语言,java,python

解法二:创建一个新的空链表,遍历俩个链表,进行新链表的尾插

(使用单链表)无头单向不循环链表

 typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
if (list1 == NULL)
	{
		return list2;
	}
	if (list2 == NULL)
	{
		return list1;
	}
  ListNode* newhead=NULL;
	ListNode* newtail=NULL;
	ListNode* pcur1=list1;
	ListNode* pcur2=list2;
	while(pcur1&&pcur2)
	{
		if(pcur1->val<pcur2->val)
		{
			if(newhead==NULL)//插入新链表
			{
				newhead=newtail=pcur1;
			}
			else
			{
        newtail->next=pcur1;
				newtail=newtail->next;
			}
				pcur1=pcur1->next;
		}
	
		else
		{
       	if(newhead==NULL)//插入新链表
			{
				newhead=newtail=pcur2;
			}
			else
			{
        newtail->next=pcur2;
				newtail=newtail->next;
			}
				pcur2=pcur2->next;
		}
	

	}
	if(pcur1==NULL)
	{
		newtail->next=pcur2;
	}
	if(pcur2==NULL)
	{
		newtail->next=pcur1;
	}
	return newhead;
}

优化解法二(使用带头单向不循环链表)

typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
if (list1 == NULL)
	{
		return list2;
	}
	if (list2 == NULL)
	{
		return list1;
	}
	 ListNode* newhead,*newtail;
  newhead= newtail=(ListNode*)malloc(sizeof(ListNode));

	ListNode* pcur1=list1;
	ListNode* pcur2=list2;
	while(pcur1&&pcur2)
	{
		if(pcur1->val<pcur2->val)
		{
			//直接插入新链表
		
		
        newtail->next=pcur1;
				newtail=newtail->next;
		
				pcur1=pcur1->next;
		}
	
		else
		{
       
        newtail->next=pcur2;
				newtail=newtail->next;
			
				pcur2=pcur2->next;
		}
	

	}
	if(pcur1==NULL)
	{
		newtail->next=pcur2;
	}
	if(pcur2==NULL)
	{
		newtail->next=pcur1;
	}
	ListNode * rethead=newhead->next;
	free(newhead);
	newhead=NULL;
	return rethead;;
}

 注:相比较与不带头链表,带头链表省略了反复判断头节点是否为空,直接插入头的后面,所带的头不带任何数据,所以返回的时候,返回头的next.

四、单链表相关经典算法OJ题4:链表的中间结点

C语言每日一练(二),c语言,开发语言,java,python

解法一:使用快慢指针

//快慢指针
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head){
    if(head==NULL)
    {
        return NULL;
    }
    ListNode * slow,*fast;
    slow=head;
    fast=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;

}

注:这种快慢指针可以运用到寻找单链表的倒数第几个节点,比如说,找倒数第3个节点,只需要让慢指针与快指针相差3个节点,当快指针走到NULL,此时慢指针为倒数第3个节点。

还有一点值得注意的是 while(fast&&fast->next)该位置判断不能颠倒,因为可能fast为空,此时先判断fast->next会报错。

五、 循环链表经典应⽤-环形链表的约瑟夫问题

著名的Josephus问题
据说著名犹太 历史学家 Josephus有过以下的故事:在罗⻢⼈占领乔塔帕特后,39 个犹太⼈与
Josephus及他的朋友躲到⼀个洞中,39个犹太⼈决定宁愿死也不要被⼈抓到,于是决定了⼀个⾃杀 ⽅式,41个⼈排成⼀个圆圈,由第1个⼈开始报数,每报数到第3⼈该⼈就必须⾃杀,然后再由下⼀ 个重新报数,直到所有⼈都⾃杀⾝亡为⽌。 然⽽Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与⾃⼰安排在第16个与第31个位置,于是逃过了这场死亡游戏。

C语言每日一练(二),c语言,开发语言,java,python

解法一:创建一个单向循环链表,遇到计数等于m的节点删除,剩下最后一个节点的val值即为所求编号

typedef   struct ListNode   ListNode;
ListNode * SLbuyNode(int x)//创造一个节点
{
    ListNode * Node=(ListNode*)malloc(sizeof(ListNode));
    Node->val=x;
    Node->next= NULL;
    return Node;
}
//创建一个循环链表
ListNode *CreatSLNode(int n)
{
    ListNode * head=SLbuyNode(1);
    ListNode * tail=head;
    for(int i=2;i<=n;i++)
    {
        tail->next=SLbuyNode(i);
        tail=tail->next;
    }
      tail->next=head;
      return tail;
}

int ysf(int n, int m ) {
   
   ListNode*  prev=CreatSLNode(n);
   ListNode*  pcur=prev->next;
   int count=1;
   while(pcur->next!=pcur)
   {
      
      if(count==m)//报到m的节点删除
      {
        prev->next=pcur->next;
        free(pcur);
        pcur=prev->next;
        count=1;
      }
      else //没报m继续往前走
      {
         prev=pcur;
         pcur=pcur->next;
         count++;
      }
      
   }
   return pcur->val;
}

C语言每日一练(二),c语言,开发语言,java,python

注意:红框若改成SLbuyNode(1),表示tail又重新开辟一块空间,和head不是同一片空间,所以连不起来。

六、 单链表相关经典算法OJ题5:分割链表 

C语言每日一练(二),c语言,开发语言,java,python

解法一:创建俩个带头单向不循环链表,将大于等于x和小于x的节点,分别放入俩个空链表,然后小链表和大链表头尾相接文章来源地址https://www.toymoban.com/news/detail-718223.html

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x){
    if(head==NULL)
    {
        return NULL;
    }

    ListNode * maxhead,*maxtail;
    ListNode * minhead,*mintail;
    maxhead= maxtail=(ListNode*)malloc(sizeof(ListNode));
  
    minhead=mintail=(ListNode*)malloc(sizeof(ListNode));
    ListNode *pcur=head;
    while(pcur)
    {
        if(pcur->val<x)
        {
            mintail->next=pcur;
            mintail=mintail->next;
            pcur=pcur->next;
        }
        else
        {
            maxtail->next=pcur;
            maxtail=maxtail->next;

            pcur=pcur->next;
        }
    }
    if(maxtail->next!=NULL)
    {
            maxtail->next=NULL;
    }
    mintail->next=maxhead->next;
   ListNode*ret= minhead->next;
   free(maxhead);
   maxhead=NULL;
   free(minhead);
   minhead=NULL;
    return ret;
}

到了这里,关于C语言每日一练(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • c语言每日一练(8)

    前言: 每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,暑假时三天之内必有一更,到了开学之后,将看学业情况更新。 1、请阅读以下程序,其运行结果是( )   A、YES       B、NO 

    2024年02月12日
    浏览(33)
  • c语言每日一练(7)

    前言: 每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,暑假时三天之内必有一更,到了开学之后,将看学业情况更新。 1、下列定义数组的语句中正确的是【多选】( ) A、 B、char str

    2024年02月13日
    浏览(44)
  • c语言每日一练(1)

    前言: 每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,暑假时三天之内必有一更,到了开学之后,将看学业情况更新。 1、执行下面程序,正确的输出是( ) A.5,7     B.7,5    C.3,8   

    2024年02月14日
    浏览(41)
  • c语言每日一练(3)

    前言: 每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,暑假时三天之内必有一更,到了开学之后,将看学业情况更新。 1、执行下面的程序段,语句3的执行次数为( ) A.n(n+2)/2    B.(

    2024年02月14日
    浏览(46)
  • c语言每日一练(5)

    前言: 每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,暑假时三天之内必有一更,到了开学之后,将看学业情况更新。 1、下面代码的结果是:( ) A. a = 8 b = 23 c = 8      B. a = 9 b= 23 c =

    2024年02月13日
    浏览(75)
  • c语言每日一练(4)

    1、有以下代码,程序的输出结果是( ) A.10       B.9       C.8       D.7 解析: 先看代码构成,代码的主要部分是一个循环,最终目标是打印出a的大小。 直接看循环,for循环先将a和b都初始化成了1,循环进行的条件是a=100,循环每次结束后,a+1 接着看循环的内部,1代码代

    2024年02月13日
    浏览(39)
  • C语言每日一练(1)

    题目: 有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 程序分析: 可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。 程序源代码: 以上实例输出结果为: 题目: 企业发放的奖金根据利润提成。利

    2024年02月12日
    浏览(52)
  • c语言每日一练(6)

    前言: 每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,暑假时三天之内必有一更,到了开学之后,将看学业情况更新。 1、如下程序的功能是( ) A、 测字符数组ch的长度 B、 将数字字

    2024年02月13日
    浏览(38)
  • c语言每日一练(15)

    前言: 每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,上学期间将看学业情况更新。 1、程序运行的结果为() A、1,5      B、2,5      C、1,6     D、2,6 解析:首先定义sum和pad为5,接

    2024年02月07日
    浏览(36)
  • c语言每日一练(11)

    前言: 每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,暑假时三天之内必有一更,到了开学之后,将看学业情况更新。 1.执行完下面一段程序后输出的值是() A、1     B、2     C、

    2024年02月11日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包