用链表实现回文判断

用链表实现回文判断

判断回文是一个非常经典的算法,其朴素实现也非常容易,如下第一段代码,用遍历字符串数组的方式实现,但本文讨论重点的是用链表实现。

//回文判断(字符数组) 
#include<stdio.h>
#include<cstring>
int main(){
	int len;
	char str[50];
	gets(str);
	len=strlen(str);
	for(int i=0;i<len/2;i++){
		if(str[i]!=str[len-i-1]){
			printf("不是回文");
			return 0; 
		}
	}
	printf("回文");
	return 0;
}

链表实现的完整代码如下:

//用链表实现回文判断 
#include<stdio.h>
#include<stdlib.h>

typedef struct node{
	char data;
	node *next;
}*LinkList,*pNode;

int len;	//该变量用于存放字符串长度 即链表长度 
int DIYstrlen(char *p){	//获取字符串长度
	int n=0;
	while(*p++)
		n++;
	return n;
}

LinkList GetEmptyList(){	//初始化链表 
	LinkList head = (pNode)malloc(sizeof(pNode));
	head->data=0;
	head->next=NULL;
	return head;
}
//字符串到链表
LinkList String2LinkList(char str[]){
	LinkList L = GetEmptyList();
	len = DIYstrlen(str);
	//printf("字符串长度为:%d\n",len); 
	int i=0;
	pNode p = L;
	while(str[i]){
		p->next = (pNode)malloc(sizeof(pNode));
		p->next->data=str[i++];
		p=p->next;
	}
	p->next=NULL;
	return L;
} 
//显示链表内容 
void show(LinkList L){
	pNode p = L->next;
	while(p){
		printf("%c ",p->data);
		p=p->next;
	}
	printf("\n");
}

//判断回文算法 
void isPalindromic(LinkList L){
	int i,n=len;//len为链表长度 
	char s[n/2];
	pNode p=L->next;
	for(i=0;i<n/2;i++){
		s[i]=p->data;
		p=p->next;
	}
	i--;	//i多加1  需要减回来 
	if(n%2==1)	//若链表长为奇数 中间的字符不需处理 直接跳过 
		p=p->next;
	while(p!=NULL&&s[i--]==p->data){
		p=p->next;
	}
	if(i==-1)
		printf("该字符串是回文");
	else 
		printf("该字符串不是回文");
} 

int main(){
	char s[100];
	printf("输入字符串:\n");
	gets(s);
	printf("链表的内容为:\n");
	LinkList L = String2LinkList(s);
	show(L);
	isPalindromic(L);
	return 0;	
}

部分代码参考自:点击此处

本程序有以下几个难点,笔者逐一解析:
1.结构体的使用,链表的建立和插入
2.字符串转为链表

字符串转为链表
转换思想:先获取字符串长度,逐个遍历字符串,采用尾插法逐个字符插入链表,读到’\0’即结束(注:’\0’的ASCII码为0,’\0’和0等效)

//字符串到链表
LinkList String2LinkList(char str[]){
	LinkList L = GetEmptyList();
	len = DIYstrlen(str);
	//printf("字符串长度为:%d\n",len); 
	int i=0;
	pNode p = L;
	while(str[i]){
		p->next = (pNode)malloc(sizeof(pNode));
		p->next->data=str[i++];
		p=p->next;
	}
	p->next=NULL;
	return L;
} 

判断回文(链表):
算法思想:将链表的前一半存入数组,链表继续往下走,此时逆序遍历数组,逐个对比,用i作为数组的下标,如遍历完之后退出循环,此时i的值小于0(即为-1),i==-1即为回文,其余值则不为回文

void isPalindromic(LinkList L){
	int i,n=len;//len为链表长度 
	char s[n/2];
	pNode p=L->next;
	for(i=0;i<n/2;i++){
		s[i]=p->data;
		p=p->next;
	}
	i--;	//i多加1  需要减回来 
	if(n%2==1)	//若链表长为奇数 中间的字符不需处理 直接跳过 
		p=p->next;
	while(p!=NULL&&s[i--]==p->data){
		p=p->next;
	}
	if(i==-1)
		printf("该字符串是回文");
	else 
		printf("该字符串不是回文");
} 

最后附上效果图:

在这里插入图片描述
在这里插入图片描述
注意在结构体只定义了char,char只支持1个字符,中文的存储需要用2个字符,故会产生如下错误,第二个的程序只支持处理英文和数字字符,如需处理中文需要稍作修改。
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值