1. 单链表实现链表逆序(详细思路)
这道题,是我毕业前在北京找实习真实碰到的一个面试题。
逆序谁不会是吧,啥?不能用数组,不能用字符串,集合。只能用node自己构建链表。
嗯,好像有点儿印象,大学学数据结构的时候都学过。
但是那会儿真是全忘了,面试官很有耐心,还教了我。唉。:)
分三步,第一步先实现链表,第二步顺序打印,第三步逆序打印,逆序打印这里有两种方案。1. 链表反转,顺序打印。2. 链表不动,逆序打印
add方法要点:
顺序就是用while输出value就行,逆序就是写个递归倒着输出value就行
重点说一下我做反转链表的思路
所有思路都在图片里面了。
PS:这应该是我最后一次主动在网上画图,太费劲儿了,以后还是手画。
2. 键盘输入一组数字,用单链表形式存储,输入完成后分别按顺序和逆序输出所输入数字。
楼主你好
具体代码如下:
#include<stdio.h>
#include<stdlib.h>
#define MAX 80
typedef struct node
{
int data;
struct node *next;
}N;
N *head=(N *)malloc(sizeof(N));//创建头结点
void Creat()
{
N *p;//用于插入新节点
N *r=head;//尾指针 开始指向头结点
printf("请输入任意个数据(用回车结束输入、空格间隔:1 2 3……)\n:");
do{
p=(N *)malloc(sizeof(N));
scanf("%d",&p->data);
r->next=p;
r=p;
}while(getchar()!='\n');
r->next=NULL;
}
void Disp()//实现顺序输出和逆序输出
{
N *p=head->next;//用于遍历单链表
int a[MAX];
int i=0,j;
printf("顺序输出:\n");
while(p)
{
printf("%d ",p->data);
a[i]=p->data;
p=p->next;
i++;
}
printf("\n逆序输出:\n");
for(j=i-1;j>=0;j--)
printf("%d ",a[j]);
printf("\n");
}
void main()
{
Creat();
Disp();
}
希望能帮助你哈
3. 单链表就地逆序
递归时,head分别用 head head1,head2 ...headn-1, headn来表示(共n+1)个节点
rHead = rev( head->next ); 此句的递归一直将参数传进来的
List * head 递归到 headn 然后判断
else if( !headn->next )
{
return headn;
}
将返回值给rHead,此时rHead指向链尾,由于在此次返回,故此次没有执行最后的else的那部分的语句,返回上一级即是 headn-1 那一级,继续执行
下面的 headn-1->next->next = headn-1;
headn-1->next = NULL; //此两句将最后两个逆序连接,
return rHead; //之后返回rHead比上一层的rHead即是执行
rHead = rev( head->next )赋值,因为递归的
口都是在这里的,如果说好理解点也可以将rHead
来编号
同理
在返回rHead后,继续执行
headn-2->next->next = headn-2;
headn-2->next = NULL;
return rHead;
.....
一直到 head时 即是原链表的第一个节点,在对其head->next = NULL,
后,此时以 rHead 所指向的节点为链头的逆序链表就形成拉.
由于不能画图,故描述得可能还是有点乱吧,不过,一句话,最好的理解就是你将递归时,head分别用 head head1,head2 ...headn-1, headn来编号表示就好理解的拉,对于 rHead 最好也标号
4. 如何用c语言实现单链表的逆置
扣着的是头节点(头子)
车是首节点(首子)
马是次节点(次子)
牙签细的是指针指向,香头发黑的是指向,铁头细的是指向。
根据步骤写程序的伪算法(3步4循环,7张图片搞定),如下:
第一个循环把马弄到车前面,
第二个循环把相弄到马前面
第三个循环把士弄到相前面
........
直到香指向为空后停止循环。
代码如下:只需要一个首结点pHead,就能把链表找到,并倒置。具体代码如下
p香=pHead->pNext;
p铁=p香->pNext;
p香->pNext=NULL;
P香=p铁
while(p香 !=NULL)
{
p铁=p香->pNext;
p香->pNext=pHead->pNext;
pHead->pNext=p香;
p香=p铁;
}
对照伪算法(三步四循环),和上面的代码是一一对应的:
第一步:香头指向首子,铁头指向次子
第二步:删掉首子指向次子(铁头所指向的那个子)的牙签
第三步:香头跟着铁头
以下循环条件:(条件:香头指向不为空)
{
循环1:铁头移动到香头的下一个指向
循环2:香头的下一个指向首子
循环3:头子的下一个跟着香头
循环4:香头跟着铁头
}
自己用道具操作几遍,然后把流程背会,以后自己根据流程写代码即可。
5. 单链表的逆序算法问题
假设有链表:h--1--2--3--4 p=h->next;,即p=1--2--3--4 h->next=NULL;即断开h与p,即h 1--2--3--4 然后while(p) 第一步:q=p,即q=1--2--3--4 第二步:p=p->next;,即p=2--3--4 第三步:q->next=h->next,因为h->next=NULL所以q->next=NULL,即把q断开为1和2--3--4 第四步:h->next=q;即h->next=1 到此链表分成两部分:h--1和2--3--4 第二次循环: 第一步:q=p,即q=2--3--4 第二步:p=p->next;,即p=3--4 第三步:q->next=h->next,因为h->next=1,所以q->next=1,即把q分成:2--1和3--4 第四步:h->next=q;即h->next=2--1 到此链表分成两部分:h--2--1和3--4 第三次循环: 第一步:q=p,即q=3--4 第二步:p=p->next;,即p=4 第三步:q->next=h->next,因为h->next=2--1,所以q->next=2--1,即把q分成:3--2--1和4 第四步:h->next=q;即h->next=3--2--1 到此链表分成两部分:h--3--2--1和4 第四次循环: 第一步:q=p,即q=4 第二步:p=p->next;,即p=NULL 第三步:q->next=h->next,因为h->next=3--2--1,所以q->next=3--2--1,即把q分成:4--3--2--1和NULL 第四步:h->next=q;即h->next=4--3--2--1 到此链表分成两部分:h--4--3--2--1和NULL p=NULL结束循环.
满意请采纳
6. 求助:单链表逆序排列问题,编程高手进!!
给你个图易理解些(图做的不好)。
称已完成逆置的链表为链表x
L:链表x的表头
L->next:链表x的第一个节点
p:待插入到链表x的节点
每次将p插入到L与L->next之间即可完成逆置
(原链表为空时该算法也能保证正确,这个你自己看看吧,不解释了)
7. 单链表就地逆置有几种方法
单链表就地逆置的两种(递归与普通循环)
1.用递归算法,对于不带头结点的单链表(a1,a2,a3,a4,a5,a6)逆置后的结果为(a6,a5,a4,a3,a2,a1)
考虑递归算法,若只有一个结点,则直接返回,若存在两个结点(a1,a2)则需要做的操作有:a2->next=a1;a1->next=NULL;return a2;
a2即新的头结点,若有三个结点,则应先将子链(a2,a3)先逆置且返回该子链的新的头结点,然后把子链(a2,a3)当作一个复合结点a2',
组成新的二元组(a1,a2')然后就可以执行前面相同的操作:a2'->next=a1;a1->next=NULL;return a3';即可,多个以上的结点可同理得到,
Node *Reverse(Node *head)
{
Node *p=head;
if(p==NULL)
return NULL;//若是空链表,返回空
Node *q=p->next;
if(q==NULL)
return p;//若只有一个结点,直接返回
else
head=Reverse(q);//记录子序列的新的头结点
q->next=p;//当前结点与已经逆置的子序列看成是前后的两个结点p,q,作相应的逆置操作
p->next=NULL;
return head; //返回新的子序列的头结点
}
2.用普通算法循环逆置(头插法重新建立带头结点的新链表)
Node *Reverse(Node *head)
{
Node *p=head->next;
if(p)//若链表不为空,则逆置,否则,空操作
{
Node *q=p->next;
head->next=NULL;//头结点分离
while(p)
{
p->next=head->next;//头插法建立链表
head->next=p;
if(q) //操作空指针的时候一定要非常注意,很容易出错
{
p=q;
q=p->next;
}
else
break;
}
}
return head;
}
8. 如何将单向链表逆序
将一条链表按逆序输出
假若头结点为L,则有;
p=q=L;/*p,q为指向头结点的两个指针*/
while(p->next!=NULL)
p=p->next;/*让p指向键表的最后一个要访问结点*/
while(1)
{
while(q->next!=p)
q=q->next;/*让q向后找,找到最后一个要打印的结点*/
printf("%d\n",p->data);
p=q;/*p向前移动一个*/
q=L;/*q又指向头结点*/
if(p=L)/*访问完了退出*/
break;
}
你参考吧