判断回文链表

该博客讨论如何判断一个链表是否为回文。通过分析和示例,提出利用栈来解决这个问题,即使偶数长度的链表,也可以通过前半段入栈,后半段与弹栈元素对比来判断。提供了C++的完整可运行源代码,并展示运行效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

判断回文链表

问题描述

请判断一个链表是否为回文链表

示例

输入: 1->2
输出: false

示例

输入: 1->2->2->1
输出: true

分析

利用栈来做,偶数情况下前半段入栈,后半段与弹栈元素做对比即可,下面代码可以正确运行,但我感觉设计得复杂了,有时间再来优化一下

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {

    public static boolean isPalindrome(ListNode head) {

        if (head == null) return true;

        Stack stack = new Stack(); //定义栈结构

        int len = computeLen(head);     //head = compute(head)? ;
        int count = 0; //辅助计数器

        /*遍历链表,进栈进一半*/
        while (head.next != null) {
            ++count;
            if (count > len / 2) break; //进一半
            stack.push(head);
            head = head.next;
        }





        /*判断是否回文*/
        /*链表长度为偶数*/
        if (len % 2 == 0) {

            for (int k = 0; k < len / 2; k++) {
                ListNode listNode = (ListNode) stack.pop();
                int i = listNode.val;


                if (i != head.val) {
                    return false;
                } else {
                    head = head.next;
                }
            }
            return true;
        }else {

            for (int k = 0; k < len / 2; k++) {
                ListNode listNode = (ListNode) stack.pop();
                int i = listNode.val;


                if (i != head.next.val) {
                    return false;
                } else {
                    head = head.next;
                }
            }
            return true;

        }


    }



    public static int computeLen(ListNode head){
        /*求链表长度*/
        int len = 1  ;
        while (head.next!=null){
            ++len  ;
            head = head.next ;
        }
        return len ;
    }}

==========update by 2020 4/16 ==================

C++完整可运行源代码(经过VS2015、devC++编译运行通过)

#include "stdio.h"    
#include "string.h"
#include "ctype.h"      
#include "stdlib.h"   
#include "io.h"  
#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 20 /* 存储空间初始分配量 */

typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */


 /* 顺序栈结构 */
typedef struct
{
	ElemType data[MAXSIZE];
	int top; /* 用于栈顶指针 */
}SqStack;

/*  构造一个空栈S */
Status InitStack(SqStack *S)
{
	/* S.data=(SElemType *)malloc(MAXSIZE*sizeof(SElemType)); */
	S->top = -1;
	return OK;
}


/* 插入元素e为新的栈顶元素 */
Status Push(SqStack *S, ElemType e)
{
	if (S->top == MAXSIZE - 1) /* 栈满 */
	{
		return ERROR;
	}
	S->top++;				/* 栈顶指针增加一 */
	S->data[S->top] = e;  /* 将新插入元素赋值给栈顶空间 */
	return OK;
}

/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
Status Pop(SqStack *S, ElemType *e)
{
	if (S->top == -1)
		return ERROR;
	*e = S->data[S->top];	/* 将要删除的栈顶元素赋值给e */
	S->top--;				/* 栈顶指针减一 */
	return OK;
}
/* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
ElemType GetTop(SqStack S, ElemType *e)
{
	if (S.top == -1)
		return ERROR;
	else
		*e = S.data[S.top];
	return *e;
}




typedef struct ListNode
{
	ElemType val;
	struct ListNode *next;
}ListNode;
typedef struct ListNode *LinkList; /* 定义LinkList */

								   /* 初始化顺序线性表 */
Status InitList(LinkList *L)
{
	*L = (LinkList)malloc(sizeof(ListNode)); /* 产生头结点,并使L指向此头结点 */
	if (!(*L)) /* 存储分配失败 */
		return ERROR;
	//(*L)->val = NULL;
	(*L)->next = NULL; /* 指针域为空 */

	return OK;
}


/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(LinkList *L, int i, ElemType e)
{
	int j;
	LinkList p, s;
	p = *L;
	j = 1;
	while (p && j < i)     /* 寻找第i个结点 */
	{
		p = p->next;
		++j;
	}
	if (!p || j > i)
		return ERROR;   /* 第i个元素不存在 */
	s = (LinkList)malloc(sizeof(ListNode));  /*  生成新结点(C语言标准函数) */
	s->val = e;
	s->next = p->next;      /* 将p的后继结点赋值给s的后继  */
	p->next = s;          /* 将s赋值给p的后继 */
	return OK;
}


int ListLength(LinkList L)
{
	int i = 0;
	LinkList p = L->next; /* p指向第一个结点 */
	while (p)
	{
		i++;
		p = p->next;
	}
	return i;
}





Status Palindrome(LinkList *L , int pos ) {
	ElemType e,e1;
	LinkList p; 
	SqStack s;

	/*初始化栈*/
	InitStack(&s);
	p = *L;

	/*判断是否空链表*/
	if (!p) {
		return FALSE;
	}
	
	/*前半元素进栈*/
	for (int i = 0; i < pos; i++) {		
		p = p->next; 
		Push(&s, p->val);
	}

	/*出栈元素与后半元素比较*/
	for (int j = 0; j < pos; j++) {
		p = p->next;


		e1 = GetTop(s, &e); /*取栈顶元素*/
		Pop(&s, &e);		/*删除栈顶元素*/

		if (p->val != e1) {
			return FALSE;
		}
	}

	return TRUE;
}



int main()
{
	ElemType e;
	LinkList L;

	Status i;


	/*初始化单链表*/
	i = InitList(&L);




	/*依次采用尾插法插入元素*/
	ListInsert(&L, 1, 1);
	ListInsert(&L, 2, 2);
	ListInsert(&L, 3, 3);
	ListInsert(&L, 4, 3);
	ListInsert(&L, 5, 2);
	ListInsert(&L, 6, 2);

	/*求长度求中间位置*/
	int j = ListLength(L);

	if (j % 2 == 0) {	/*回文链表一定是偶数*/
		int pos = j / 2;

		int k = Palindrome(&L, pos);
		if (k == TRUE) {
			printf("true");
		}
		else {
			printf("false");
		}
	}
	

	

	system("pause");
	return 0;



}

运行效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值