判断一条单向链表是不是"回文"

说明:转载请注明出处http://blog.csdn.net/yuanwei1314/article/details/40828455

题目:

    判断一条单向链表是不是"回文"

 

思路一:采用快慢指针,慢指针入栈,当快指针为NULL时,出栈和慢指针比较即可。时间复杂度O(n),空间复杂度O(n)。

优点:比较好实现,且没有修改链表

缺点:需要分配内存

 

#include <stdio.h>
#include <stdlib.h>
#include <stack>
typedef int elem;
typedef struct node
{
   elem data;
   struct node *next;
}LNode, *LINKLIST;
/*采用快慢指针方式,将慢指针的结点添加到栈中
  当快指针到NULL时,将慢指针的结点与快指针比较即可*/
bool isPalindromeList(LINKLIST list)
{
   LNode* fast = list->next;
   LNode* slow = list->next;
   bool flag = false;/*奇偶判断需要*/
   stack<elem> s;
   
   while (fast != NULL)
   {
        s.push(slow->data);
        /*快指针走两步*/
        fast = fast->next;
        slow = slow->next;
        if (fast != NULL)
        {
            fast = fast->next;
        }
        else
        {
            flag = true;
        }
   }
   /*如果是奇结点,出栈一个*/
   if (flag)
   {
        s.pop();
   }
   
   /*慢指针和栈直接比较*/
   while (slow!=NULL && !s.empty())
   {
        if (slow->data != s.top())
        {
            return false;
        }
        slow = slow->next;
        s.pop();
   }
   return true;
}
/*采用尾插法,创建单链表*/
void createList(LINKLIST list, elem data)
{
    LNode* p = list;
    LNode* newNode;
    while (p->next != NULL)
    {
        p = p->next;
    }
    newNode = (LNode*)malloc(sizeof(LNode));
    newNode->next = NULL;
    newNode->data = data;
    p->next = newNode;
}
/*打印单链表*/
void printList(LINKLIST list, void(*print)(elem))
{
    LNode* p = list->next;
    while (p != NULL)
    {
         print(p->data);
         p = p->next;
    }
    printf("\n");
}
/*打印结点值*/
void printElem(elem data)
{
    printf("%d\t", data);
}
int main()
{
   LINKLIST list = NULL;
   elem data[] = {1,2,3,3,2,1};
   int i;
   list = (LINKLIST)malloc(sizeof(LNode));
   list->next = NULL;
   list->data = 0;
   for (i=0; i<6; i++)
   {
        createList(list, data[i]);
   }
   printList(list, printElem);
   if (isPalindromeList(list))
   {
        printf("TRUE\n");
   }
   else
   {
        printf("FALSE\n");
   }
   return 0;
}

 

思路二:采用快慢指针,当快指针为NULL时,翻转慢指针。比较前半部分链表和翻转链表即可。时间复杂度O(n),空间复杂度O(1)。

优点:节约空间

缺点:改变了链表的值

 

#include <stdio.h>
#include <stdlib.h>
#include <stack>
typedef int elem;
typedef struct node
{
   elem data;
   struct node *next;
}LNode, *LINKLIST;
LNode* reverseLink(LNode* begin, LNode* end)
{
      LNode* pre = NULL;
      LNode* q;
      LNode* p = begin;
      LNode* head = NULL;
      
      while (p != end)
      {
           q = p->next;
           if (q == end)
           {
                head = p;
           }
           p->next = pre;
           pre = p;
           p = q;
      }
      
      return head;
}
/*采用快慢指针方式,当到中间时逆转后半部分指针
  挨个比较,如果满足相同则返回true*/
bool isPalindromeList(LINKLIST list)
{
     LNode* slow = list->next;
     LNode* fast = list->next;
     LNode* p = list->next;
     LNode* head = NULL;
     
     while (fast != NULL)
     {
        slow = slow->next;
        fast = fast->next;
        
        if (fast != NULL)
        {
            fast = fast->next;
        }
     }
     
     /*获取翻转过后的头结点*/
     head = reverseLink(slow, NULL);
     while (p!=NULL && head!=NULL)
     {
        if (p->data != head->data)
        {
            return false;
        }
        p = p->next;
        head = head->next;
     }
     
     return true;
}
/*采用尾插法,创建单链表*/
void createList(LINKLIST list, elem data)
{
    LNode* p = list;
    LNode* newNode;
    while (p->next != NULL)
    {
        p = p->next;
    }
    newNode = (LNode*)malloc(sizeof(LNode));
    newNode->next = NULL;
    newNode->data = data;
    p->next = newNode;
}
/*打印单链表*/
void printList(LINKLIST list, void(*print)(elem))
{
    LNode* p = list->next;
    while (p != NULL)
    {
         print(p->data);
         p = p->next;
    }
    printf("\n");
}
/*打印结点值*/
void printElem(elem data)
{
    printf("%d\t", data);
}
/*TEST*/
int main()
{
   LINKLIST list = NULL;
   elem data[] = {1,2,3,2,1,5};
   int i;
   list = (LINKLIST)malloc(sizeof(LNode));
   list->next = NULL;
   list->data = 0;
   for (i=0; i<6; i++)
   {
        createList(list, data[i]);
   }
   printList(list, printElem);
   if (isPalindromeList(list))
   {
        printf("TRUE\n");
   }
   else
   {
        printf("FALSE\n");
   }
   return 0;
}


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值