C语言(十九)

1、链表逆置
输入:输入多个结点构建链表L
输出:输出链表逆置后的序列
优化目标:减少时间和空间复杂度
思路:之前有写过不带头结点的单链表逆置,今天补充一下其他几种情况。单链表分为带头节点和不带头节点两种,逆置思路有两种,第一种是采用头插法重新建立新的单链表,该方法直接遍历链表,每次将当前结点添加到新链表的头部;第二种定义三个工作指针*pre, *p, *r,分别表示三个连续结点,将p->next指向pre,但同时p的后继节点会断开,所以需要用r保存其后继节点。

带头结点单链表(头插法):

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *createlist(); /*裁判实现,细节不表*/
struct ListNode *reverse( struct ListNode *L );
void printlist( struct ListNode *L )
{
     struct ListNode *p = head;
     while (p) {
           printf("%d ", p->data);
           p=p->next;
     }
     printf("\n");
}

int main()
{
    struct ListNode  *L;
    L=createlist();
    reverse(L);
    printlist(L);
        return 0;
}

void reverse(struct ListNode *L)
{
	struct ListNode *p;
    p=L.next;
    L.next=NULL;//将链表置空
    while(p!=NULL){
        struct ListNode *tmp;
        tmp=p->next;
        p->next=L.next;
        L.next=p;//头插法
        p=tmp;
    }
	
}


带头结点单链表(3个工作指针):

void Reverse_2(struct ListNode *L){
    struct ListNode *pre = NULL, *p = NULL, *r = NULL;
    r = L.next;
    while(r!=NULL){
        if(p==NULL){	//这样做的目的是处理结点数小于等于1的情况
            p=r;
            r=r->next;
            p->next=NULL;
            continue;
        }
        pre=p;
        p=r;
        r=r->next;
        p->next=pre;
    }
    L.next=p;
}

不带头结点单链表(头插法):

LNode* Reverse_3(struct ListNode *L){
    struct ListNode *p;
    p=NULL;
    while(L!=NULL){
       struct ListNode *tmp=L->next;	//会发生断链,因此需保存后继节点
        L->next=p;
        p=L;
        L=tmp;
    }
    return p;
}

不带头结点单链表(3个工作指针):

LNode* Reverse_4(struct ListNode *L){
    struct ListNode *pre = NULL, *p = NULL, *r = NULL;
    r=L;
    while(r!=NULL){
        if(p==NULL){
            p=r;
            r=r->next;
            p->next=NULL;
            continue;
        }
        pre=p;
        p=r;
        r=r->next;
        p->next=pre;
    }
    return p;
}

2、小球下落问题
一球从100 米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10 次反弹多高?
输入:无
输出:输出小球第10次落地时经过的距离以及第十次反弹高度
优化目标:无

#include <stdio.h>
#include <stdlib.h>
 
int main()
{
    int i;
    double sn=100;
    double hn=sn/2;
    for(i=2;i<=10;i++)//从第一次弹起开始计算
    {
        sn+=2*hn;
        hn/=2;
    }
    printf("Total %lf\n",sn);
    printf("h10 is %lf\n",hn);
    return 0;
}

ps:之前练习了小球下落的递归题目,此题可采用一般方法。

3、递归逆序输出字符
输入:输入n个字符
输出:逆序输出字符
优化目标:无

#include <stdio.h>
void print(int n)
{
    char c;
    if(n==1){
    	c=getchar();
    	printf("Output:\n");
    	putchar(c);
	}
	else{
		c=getchar();
		print(n-1);
		putchar(c);
	}
}
int main()
{
	int n;
    printf("Input chars:\n");
    scanf("%d",&n)
    print(n);
    printf("\n");
    return 0;
}

ps:定要在putchar()之前调用递归函数。另外getchar()是从输入流中获取一个字符,所以输入的时候格式就是abcde,并非像scanf那样输入一个字符后,按回车或者Tab后再输入下一个字符。
4、求一个整数的位数且逆序打印
输入:输入整型变量i
输出:输出i的位数且逆序打印
优化目标:无

#include <stdio.h>
#include <stdlib.h>
int digits(int n);
int main()
{
    int i;
    printf("Please input an integer!\n");
    scanf("%d",&i);
    printf("It contains %d digits!\n",digits(i));
    return 0;
}
int digits(int n){
	int d=0;
	while(n>0){
		printf("%d", n%10);
		n/= 10;
		d++;//计算位数
	}
	printf("\n");
	return d;
}

总结:今天练习了一些pta上的基础题,并复习了部分之前练习的链表题,明天还是计划复习链表的知识。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值