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上的基础题,并复习了部分之前练习的链表题,明天还是计划复习链表的知识。