栈和队列的应用——回文数判断

前言

用栈和队列实现回文数判断

代码及易错点说明

  • 库函数调用及栈和队列相应结构体声明
#include 
#include 
#include 
#include 

typedef char DataType;

//队列数据元素结构
typedef struct node {
	DataType info;
	struct node *next;
} QueueData;

typedef struct queueRecord {
	QueueData  *front, *rear ;
} LINKQUEUE;

typedef struct queueRecord *PLinkQueue;

struct stack {
	DataType element;  //数据元素
	struct stack *next; //指向下一个数据元素的指针
};

typedef struct stack *PtrToNode;
typedef PtrToNode Stack;
  • 队列相关操作
PLinkQueue createEmptyQueue_link( ) {
	//请在此处填写代码,完成相应功能
	/*-------begin----------*/
	PLinkQueue head;
	head = (PLinkQueue)malloc(sizeof(struct queueRecord));
	if(head==NULL) {
		printf("create head node failed!");
		return NULL;
	}

	head->front=NULL;
	head->rear=NULL;
	return head;
	/*-------end----------*/
}

int isEmptyQueue_link(PLinkQueue queue) {
	//请在此处填写代码,完成相应功能
	/*-------begin----------*/
	return queue->front==NULL;//为空返回1,不为空返回0
	/*-------end----------*/
}

void enQueue_link(DataType x, PLinkQueue queue) {
	//将数据元素x插入队尾。实质:生成一个struct node类型的结点,并给相应成员赋值后插入队尾
	//请在此处填写代码,完成相应功能
	/*-------begin----------*/
	QueueData *s = (QueueData*)malloc(sizeof(struct node));
if(s==NULL){
	printf("create a new node for queue failed!");

}
		
		s->info=x;
		s->next=NULL;

	if(queue->front==NULL) {
		queue->front=s;
	} else{
		queue->rear->next=s;
	}
		queue->rear=s;
	/*-------end----------*/
}


DataType deQueue_link(PLinkQueue Q) {
	//取出Q队列的队首结点,返回该结点的数据元素
	//请在此处填写代码,完成相应功能
	/*-------begin----------*/
	if(!isEmptyQueue_link(Q)) {

			QueueData *s;
			s=Q->front;
			DataType x=Q->front->info;
			Q->front=s->next;
			free(s);
		
			return x;
		
	}
	/*-------end----------*/

}

注意点:
if(queue->front==NULL) { queue->front=s; } else{ queue->rear->next=s; } queue->rear=s;
入队当中的这一段代码,queue->rear=s;是无论传入队列属于哪种类型都应该进行的操作

  • 栈的相关操作
int isEmpty(Stack s) {
	return  s->next==NULL;
}

/*
   函数名:createStack
   函数功能:创建一个空栈,实际上只需要初始化栈头结点
   函数参数:无
   返回值:栈头结点指针
*/
Stack createStack(void) {
	Stack s ;
	s =(PtrToNode)malloc(sizeof(struct stack));
	if(s==NULL){
		printf("create node for stackhead failed!");
		return NULL;
	}
	s->next = NULL;//栈顶 

	return s;
}

/*
   函数名:push
   函数功能:向栈中压人一个数据元素值为x
   函数参数:待压栈的数据元素,栈头结点指针
   返回值:无
*/
void push(DataType  x,Stack s) {
	//表头作为栈顶
	PtrToNode temp ;
	temp=(PtrToNode)malloc(sizeof(struct stack));
	if(temp==NULL){
		printf("create node for new node failed!");
	
	}
	temp->element = x;
	temp->next = s->next;
	s->next = temp;
}

/*
   函数名:pop
   函数功能:弹出栈顶元素并返回元素值
   函数参数:栈头结点指针
   返回值:栈顶元素的值
*/
DataType pop(Stack s) {
	PtrToNode temp;
	DataType t;
	if(!isEmpty(s)) {
		temp = s->next;
		t = temp->element;
		s->next = temp->next;
		free(temp);
		return t;
	}
	else printf("stack is emtpty!");
}

DataType top(Stack s) {
	if(isEmpty(s)==0) return s->next->element ;
else{
	printf("nothing in top");
	return NULL;
}
}
  • 回文函数
int ishuiwen(DataType src[]) {
	/*-------begin----------*/
	//printf("输入的字符串为:");
	//printf("%s",src);

	PLinkQueue s = createEmptyQueue_link( );
     //printf("succeed in create queue!");
	Stack stack = createStack();
	//printf("succeed in create stack!");
	int i=0;
	while(src[i]) {
		enQueue_link(src[i],s);
		//printf("第%d号元素入队成功!",i);
		push(src[i],stack);
		//printf("第%d号元素入栈成功!",i);
		i++;
	}
//printf("succeed in enqueue and push!");

	int flag=1;
	if(isEmptyQueue_link(s)){
		flag=0;
		 printf("queue is empty!");
	}
	if(isEmpty(stack)){
		flag=0;
		 printf("stack is empty!");
	}	
	while((!isEmptyQueue_link(s))&&(!isEmpty(stack))){
		if(pop(stack)!=deQueue_link(s)) {
//			printf("%c",pop(stack));
//			printf("%c",deQueue_link(s));
//			printf("该元素不符合!");
			flag=0;
			break;
		}
	}

	if(flag==1) {
		return 1;
	} else {
		return 0;
	}
	

}
  • 主函数
int main(void) {
    DataType str[20];
	scanf("%s",str);
	if(ishuiwen(str)) {
		printf("yes");
	} else {
		printf("no");
	}

	return 0;
}

最后再提醒一下:我记得原来的兄台写的代码栈和队列的元素类型定义不一致,一个是char,另一个是int,我有种大胆的猜测,ta应该是将再之前栈相关的闯关代码直接copy到这里来而没有修改数据类型,所以最初匹配失败。所以还是建议小伙伴们考虑栈和队列的结构都使用同一个,再typedef不同的名字,避免混淆。

另外,虽然当代码量较大程序较复杂时时用全局变量可能有害,但对于这种解决的是同一组数据的问题,用typedef将DataType确定下来是很有帮助的,0和‘0’毕竟真的不一样不是吗?

结语

不要直接copy人家的代码!不要直接copy人家的代码!不要直接copy人家的代码!重要的事情说三遍!
我花了两个多小时排错的泪,都是当初敷衍作业的时候脑子进的水!
学期末老师开启了查重功能,我和n个八竿子打不着的同学代码百分之百重合,想想真是天雷滚滚……估计是大家都打开了同一个搜索引擎、找到了同一个页面吧……

这不是重点,重点是老师给了一次机会,说想证明自己不是抄袭的同学要带上源代码现场改功能,能改出来说明真的会了、也不是简单复制粘贴的。

于是问题来了,我打开了这段几个月前忘了从哪里找来的代码,一在本地运行、发现无法满足测试样例,估计也只是侥幸过了评测平台的测试吧?
于是我开始修改这段代码,从只是无法输出正确结果到出现更大的问题、再到将问题逐一排查并解决,我用了两个多小时,害,早知今日何必当初呢?要是自己从头到尾写一遍估计不需要一个小时吧?
这位兄台写的代码本身和我的代码习惯并不一致,很多地方的处理方式都不同,我排查起来真的很头痛!(当然各位现在看到的除了变量名之外已经基本被我魔改过了)
不过也有很多经验教训和收获,比如:不要抄作业,要借鉴人家的思路,然后自己动手丰衣足食;再比如,其实在这个排查的过程中也是更深入地理解了一些原理和细节,人没得点教训是不长记性的,什么问题都不出光看看还真就以为自己全懂了……排查自己的代码错误也是同理。
希望到时候再次魔改代码顺顺利利!

你可能感兴趣的:(数据结构与算法,衔接程序设计与数据结构,数据结构,c语言,栈,队列)