用链表实现回文判断
判断回文是一个非常经典的算法,其朴素实现也非常容易,如下第一段代码,用遍历字符串数组的方式实现,但本文讨论重点的是用链表实现。
//回文判断(字符数组)
#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个字符,故会产生如下错误,第二个的程序只支持处理英文和数字字符,如需处理中文需要稍作修改。