[英]Reversing a linked list without modifying the head pointer
我正在编写一个程序来检查单链列表是否是回文。 我的方法如下:
反向操作会修改头指针。 为了不修改head指针,我创建了一个temp
变量来指向head并使用相同的反向列表并返回temp
指针。 操作如下:
struct node* reverse()
{
struct node *temp=head;
struct node *curr=temp, *prev=NULL, *next=NULL;
while(curr!=NULL)
{
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
temp = prev;
return temp;
}
现在,我的回文功能实现如下:
int isPalindrome()
{
struct node *temp=head, *rev=head;
rev = reverse();
while(temp!=NULL)
{
if(temp->data != rev->data)
return 0;
temp = temp->next;
rev = rev->next;
}
return 1;
}
如果反向列表和原始列表节点不匹配,则返回0。否则返回1。
它适用于一些测试案例。 但是当列表是1-> 4-> 3-> 2-> 1时。 它返回1,但应该返回0。
在锻炼时,我发现, rev
函数修改了头指针。 现在,我的列表只有一个节点。
输出如下所示:
reverse
函数后,第三个列表将打印原始列表 反转原始头后,指向反转列表中的最后一个元素,这就是为什么您在第三个输出中仅看到一个元素的原因。 有几个选项供您选择:
使用双链表。 从头和尾同时以相反的方向移动。
反转之前,请复制原始列表并比较两个列表。
使用堆栈或其他数据结构来提供帮助(类似于上面的选项2)。
修改算法以仅使用原始列表。
显然,功能reverse
是错误的,因为它将建立一个新列表。 这意味着它必须基于原始列表的节点为反向列表创建新的节点。 也就是说,它必须使用标准函数malloc
在内存中分配其节点。
另外,定义一个将比较两个列表的函数在逻辑上更加一致。 使用此功能,您可以说列表是否为回文。
这是一个演示程序,您可以将其用作自己程序的示例。
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
void push_front( struct node **head, int data )
{
struct node *n = malloc( sizeof( struct node ) );
n->data = data;
n->next = *head;
*head = n;
}
void display( struct node *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d ", head->data );
}
printf( "\n" );
}
struct node * reverse_copy( struct node *head )
{
struct node *rev_head = NULL;
for ( ; head != NULL; head = head->next )
{
push_front( &rev_head, head->data );
}
return rev_head;
}
int equal( struct node *head1, struct node *head2 )
{
while ( head1 != NULL && head2 != NULL && head1->data == head2->data )
{
head1 = head1->next;
head2 = head2->next;
}
return head1 == NULL && head2 == NULL;
}
void free_list( struct node **head )
{
struct node *n = *head;
while ( n != NULL )
{
struct node *tmp = n;
n = n->next;
free( tmp );
}
*head = NULL;
}
struct node *head;
int main(void)
{
push_front( &head, 1 );
push_front( &head, 2 );
push_front( &head, 3 );
push_front( &head, 4 );
push_front( &head, 1 );
display( head );
struct node *rev_head = reverse_copy( head );
if ( equal( head, rev_head ) )
{
printf( "The list is a palindrome\n" );
}
else
{
printf( "The list is not a palindrome\n" );
}
free_list( &head );
free_list( &rev_head );
push_front( &head, 1 );
push_front( &head, 2 );
push_front( &head, 3 );
push_front( &head, 2 );
push_front( &head, 1 );
display( head );
rev_head = reverse_copy( head );
if ( equal( head, rev_head ) )
{
printf( "The list is a palindrome\n" );
}
else
{
printf( "The list is not a palindrome\n" );
}
free_list( &head );
free_list( &rev_head );
return 0;
}
程序输出为
1 4 3 2 1
The list is not a palindrome
1 2 3 2 1
The list is a palindrome
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.