数据结构day6(2023.7.20)

一、Xmind整理:

 

二、课上练习:

练习1:个栈的入栈次序ABCDE,则栈的不可能的输出序列是(D)

A.ABCDE          B.DECBA          C.EDCBA          D.DCEAB

       栈的特点是先进后出,后进先出,D不符合该思想,根据题意,可以推测D选项首先入栈的是ABCD,然后D出,C出,E进入,E出,但在这种情况下,B应当比A先出栈。

练习2:顺序栈

 

练习3:顺序栈的结构体定义

 

练习4:顺序栈的插入 


/*
 * function:    入栈
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int list_stack_push(datatype e,StackList *stack)
{
    //1.判断栈是否创建
    //2.判断栈是否为满
    if(NULL==stack || stack->top==MAXSIZE-1)
    {
    puts("push  stack  error");
    return -1;
    }
    //3.入栈:先加后压
    //stack->top++;
stack->data[++stack->top]=e;
    return 0;
}

练习5:顺序栈的删除

/*
 * function:    出栈
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int list_stack_pop(StackList *stack)
{
    //1.判断栈是否创建
    //2.判断栈是否为空
    if(NULL==stack || stack->top==-1)
    {
    puts("pop error");
    return -1;
    }
    //3.出栈:先弹后减
    printf("pop data is:%d\n",stack->data[stack->top--]);
//    stack->top--;
    return 0;
}

练习6:顺序栈的遍历

/*
 * function:    顺序栈的输出
 * @param [ in] 
 * @param [out] 
 * @return      无
 */
void stack_output(StackList *stack)
{
    //1.判断栈是否创建
    //2.判断栈是否为空
    if(NULL==stack || stack->top==-1)
    {
    puts("output error");
    return;
    }
    //3.输出
    for(int i=0;i<=stack->top;i++)
    {
    printf("%d\t",stack->data[i]);
    }
    puts("");
}

练习7:顺序栈的创建

/*
 * function:    创建栈
 * @param [ in] 
 * @param [out] 
 * @return      
 */
StackList *create_stack()
{
StackList *stack=(StackList *)malloc(sizeof(StackList));
    if(NULL == stack)
    {
    return NULL;
    }
    //栈顶置空
stack->top=-1;
    memset(stack->data,0,sizeof(stack->data));
    return stack;
}

练习8:链栈

 

练习9:链栈节点创建【单链表节点创建】

/*
 * function:    创建一个节点
 * @param [ in] 
 * @param [out] 
 * @return      
 */
LinkStack create_node()
{
LinkStack node=(LinkStack)malloc(sizeof(struct Node));
    if(NULL==node)
    return NULL;
node->data=0;
node->next=NULL;
    return node;//0x10
}

练习10:链栈插入【单链表头插】

/*
 * function:    链栈的入站
 * @param [ in] 
 * @param [out] 
 * @return      
 */

LinkStack link_stack_push(datatype e,LinkStack top)
{
    //在堆区创建一个节点
LinkStack node=create_node();//在堆区申请一个节点
node->data=e;//数据域赋值为e
    //node节点链接到链表中
node->next=top;
top=node;
    return top;//因为自定义函数指针的改变不影响实参,需要返回
}

练习11:链栈删除【单链表头删】

/*
 * function:    头删除
 * @param [ in] 
 * @param [out] 
 * @return      
 */
LinkStack link_stack_pop(LinkStack top)
{
    //判断链表是否为空
    if(NULL==top)
    {
    return top;
    }
    if(top->next==NULL)
    {
    free(L);
    L=NULL;
    }
    else
    {
    LinkStack q=top->next;
    top->data=q->data;
    top->next=q->next;
    free(q);
    q=NULL;
    }
return top;


}

练习12:链栈遍历【单链表遍历】

/*
 * function:    循环遍历
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int link_output(LinkStack top)

{
    //判断是否创建
    //判断是否为空
    if(NULL==top )
    {
    return -1;
    }
    while(top!=NULL)
    {
    printf("%d\t",top->data);
    top=top->next;
    }
    puts("");
}

栈的整体代码:

stack_head.h:

#ifndef __STACK_HEAD_H__
#define __STACK_HEAD_H__

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 4
typedef int datatype;
typedef struct
{
	//栈顶
	int top;
	//数据元素
	datatype data[MAXSIZE];
}StackList;

int list_stack_pop(StackList *stack);
StackList *create_stack();
int list_stack_push(datatype e,StackList *stack);
void stack_output(StackList *stack);

//定义单链表节点结构体
typedef struct Node
{
	//数据域:数据元素
	datatype data;
	//指针域:存储下一个节点的地址
	struct Node *next;
}*LinkStack;


LinkStack link_stack_push(datatype e,LinkStack top);
int link_output(LinkStack top);
LinkStack link_stack_pop(LinkStack L);

#endif


stack_test.c:

#include "stack_head.h"
/*
 * function:    创建栈
 * @param [ in] 
 * @param [out] 
 * @return      
 */
StackList *create_stack()
{
	StackList *stack=(StackList *)malloc(sizeof(StackList));
	if(NULL == stack)
	{
		return NULL;
	}
	//栈顶置空
	stack->top=-1;
	memset(stack->data,0,sizeof(stack->data));
	return stack;
}
/*
 * function:    入栈
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int list_stack_push(datatype e,StackList *stack)
{
	//1.判断栈是否创建
	//2.判断栈是否为满
	if(NULL==stack || stack->top==MAXSIZE-1)
	{
		puts("push  stack  error");
		return -1;
	}
	//3.入栈:先加后压
	//stack->top++;
	stack->data[++stack->top]=e;
	return 0;
}
/*
 * function:    顺序栈的输出
 * @param [ in] 
 * @param [out] 
 * @return      无
 */
void stack_output(StackList *stack)
{
	//1.判断栈是否创建
	//2.判断栈是否为空
	if(NULL==stack || stack->top==-1)
	{
		puts("output error");
		return;
	}
	//3.输出
	for(int i=0;i<=stack->top;i++)
	{
		printf("%d\t",stack->data[i]);
	}
	puts("");
}
/*
 * function:    出栈
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int list_stack_pop(StackList *stack)
{
	//1.判断栈是否创建
	//2.判断栈是否为空
	if(NULL==stack || stack->top==-1)
	{
		puts("pop error");
		return -1;
	}
	//3.出栈:先弹后减
	printf("pop data is:%d\n",stack->data[stack->top--]);
//	stack->top--;
	return 0;
}
/*
 * function:    创建一个节点
 * @param [ in] 
 * @param [out] 
 * @return      
 */
LinkStack create_node()
{
	LinkStack node=(LinkStack)malloc(sizeof(struct Node));
	if(NULL==node)
		return NULL;
	node->data=0;
	node->next=NULL;
	return node;//0x10
}/*
 * function:    链栈的入站
 * @param [ in] 
 * @param [out] 
 * @return      
 */

LinkStack link_stack_push(datatype e,LinkStack top)
{
	//在堆区创建一个节点
	LinkStack node=create_node();//在堆区申请一个节点
	node->data=e;//数据域赋值为e
	//node节点链接到链表中
	node->next=top;
	top=node;
	return top;//因为自定义函数指针的改变不影响实参,需要返回
}
/*
 * function:    循环遍历
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int link_output(LinkStack top)

{
	//判断是否创建
	//判断是否为空
	if(NULL==top )
	{
		return -1;
	}
	while(top!=NULL)
	{
		printf("%d\t",top->data);
		top=top->next;
	}
	puts("");
}
/*
 * function:    头删除
 * @param [ in] 
 * @param [out] 
 * @return      
 */
LinkStack link_stack_pop(LinkStack top)
{
	//判断链表是否为空
	if(NULL==top)
	{
		return top;
	}
	if(top->next==NULL)
	{
		free(L);
		L=NULL;
	}
	else
	{
		LinkStack q=top->next;
		top->data=q->data;
		top->next=q->next;
		free(q);
		q=NULL;
	}
	return top;


}

stack_main.c:

#include "stack_head.h"
int main(int argc, const char *argv[])
{
	/*
	StackList *stack=create_stack();
	char continu;
	datatype e;
	int flag;
	do
	{
	//入栈
		printf("please enter e:");
		scanf("%d",&e);
		flag=list_stack_push(e,stack);
		if(flag==-1)
			break;
		printf("Please enter whether you will continue");
		scanf(" %c",&continu);

	}while(continu!='N'&&continu!='n');
	
	stack_output(stack);
	do
	{
		flag=list_stack_pop(stack);

		if(flag==-1)
			break;
		printf("Please enter whether you will continue");
		scanf(" %c",&continu);

	}while(continu!='N'&&continu!='n');
	
	stack_output(stack);
	
*/
	LinkStack top=NULL;
	char continu;
	datatype e;
	int flag;
	do
	{
	//入栈
		printf("please enter e:");
		scanf("%d",&e);
		
		top=link_stack_push(e,top);
		
		printf("Please enter whether you will continue");
		scanf(" %c",&continu);

	}while(continu!='N'&&continu!='n');
	
	link_output(top);
	do
	{
		
		top=link_stack_pop(top);
		printf("Please enter whether you will continue");
		scanf(" %c",&continu);

	}while(continu!='N'&&continu!='n');
	
	link_output(top);
	return 0;
}

练习13:顺序队列

 

练习14:顺序队列创建

/*
 * function:    在堆区申请空间
 * @param [ in] 
 * @param [out] 
 * @return      返回地址
 */
QueueList *create_queue()
{
QueueList  *queue=(QueueList *)malloc(sizeof(QueueList));
    if(NULL==queue)
    return NULL;

queue->front=queue->rear=0;
    memset(queue->data,0,sizeof(queue->data));
    return queue;
}

练习15:顺序队列入队

/*
 * function:    入队
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int enqueue(datatype e,QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否满
    if(NULL==queue || queue->rear==MAXSIZE)
    {
    puts("enqueue error");
    return -1;
    }
    //3.入队:在队尾插入
queue->data[queue->rear++]=e;
//    queue->rear++;
    return 0;
    
}

练习16:顺序队列出队

/*
 * function:    出队
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int delqueue(QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否为空
    if(NULL==queue || queue->front==queue->rear)
    {
    puts("delqueue error");
    return -1;
    }
    //3.出队:出队在队头
    printf("delqueue data is:%d\n",queue->data[queue->front++]);
//    queue->front++;

}

练习17:顺序队列遍历

/*
 * function:    循环输出队列
 * @param [ in] 
 * @param [out] 
 * @return      无
 */
void output(QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否为空
    if(NULL==queue || queue->front==queue->rear)
    {
    puts("output error");
    return;
    }
    //3.从队头到队尾输出
    for(int i=queue->front;i<queue->rear;i++)
    {
    printf("%d\t",queue->data[i]);
    }
    puts("");
}

练习18:循环队列

 

练习19:循环队列入队

/*
 * function:    循环队列入队
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int enqueue(datatype e,QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否满
    if(NULL==queue ||queue->front==(queue->rear+1)%MAXSIZE)
    {
    puts("enqueue error");
    return -1;
    }
    //3.入队:在队尾插入
queue->data[queue->rear]=e;
queue->rear=(queue->rear+1)%MAXSIZE;
    return 0;
    
}

练习20:循环队列出队

/*
 * function:    出队
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int delqueue(QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否为空
    if(NULL==queue || queue->front==queue->rear)
    {
    puts("delqueue error");
    return -1;
    }
    //3.出队:出队在队头
    printf("delqueue data is:%d\n",queue->data[queue->front]);
queue->front=(queue->front+1)%MAXSIZE;
    return 0;

}

练习21:循环队列的遍历

/*
 * function:    循环输出队列
 * @param [ in] 
 * @param [out] 
 * @return      无
 */
void output(QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否为空
    if(NULL==queue || queue->front==queue->rear)
    {
    puts("output error");
    return;
    }
    //3.从队头到队尾输出
    for(int i=queue->front;i!=queue->rear;i=(i+1)%MAXSIZE)
    {
    printf("%d\t",queue->data[i]);
    }
    puts("");
}

练习22:循环队列个数计算

/*
 * function:    计算循环队列个数
 * @param [ in] 
 * @param [out] 
 * @return      
 */
int loop_queue_count(QueueList *queue)
{
 return (MAXSIZE-queue->front+queue->rear)%MAXSIZE;
}

练习23:链式队列

 

练习24:链式队列节点创建【单链表节点创建】

//创建节点
queue  *CreateLink()
{
	//创建队列:头节点,尾节点【指向单向链表的头以及尾】
	queue *q=(queue *)malloc(sizeof(queue));
	if(q==NULL)
		return NULL;
	//创建单向链表的头节点
	Node *L=(Node *)malloc(sizeof(Node));
	if(L==NULL)
		return NULL;
	L->len=0;//对单向链表头结点的数据域赋值,链表为空
	L->next=NULL;//单向链表头结点没有后继节点
	
	q->front=L;//队头指向单向链表的第一个节点
	q->rear=L;//队尾指针指向单向链表的最后一个节点
	return q;
}

练习25:链式队列入队【单链表尾插】

void EnqueueLink(queue *q,datatype e)
{
	//1.判断队列是否创建成功
	if(q==NULL)
		return;
	//2.入队
	Node *p=(Node *)malloc(sizeof(Node));
	if(p==NULL)
		return;
	p->data=e;
	p->next=NULL;
	
	//3.入队
	q->rear->next=p;
	q->rear=p;
	q->front->len++;
}

练习26:链式队列出队【单链表头删】

//链式队列的出队
//成功返回出队的数据,
int dequeueLink(queue *q)
{
	//1.判断队列是否存在
	//2.判断队列是否为空
	if(q==NULL || q->front->next==NULL)
		return -1;
	//3.出队
	Node *p=q->front->next;
	int data=p->data;
	q->front->next=p->next;
	free(p);
	p=NULL;
	q->front->len--;
	return data;
}

练习27:链式队列遍历【单链表的输出】

//链是队列的遍历
void LinkShow(queue *q)
{
	printf("\n");
	Node *p=q->front;
	while(p->next)
	{
		p=p->next;
		printf("%d\t",p->data);
	}
	printf("\n");
}

练习28:释放空间

//释放头节点后面的节点
	int t=q->front->len;
	for(int i=0;i<t;i++)
	{
		dequeueLink(q);
	}
	free(q->front);//删除头节点
	free(q);//释放队列的空间
	q=NULL;//q释放没有指向,防止野指针

练习29:直接插入排序

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	int m,t,j;
	int arr[100];
	printf("请问你要插入几个数:");
	scanf("%d",&m);
	for(int i=0;i<m;i++)
	{
		printf("请输入第%d个数:",i+1);
		scanf("%d",&arr[i]);
	}
	int *p=arr;
	for(int i=1;i<m;i++)
	{
		t=*(p+i);
		for(j=i-1;j>=0;j--)
		{
			if(t<*(p+j))
			{
				*(p+j+1)=*(p+j);
			}
			else
				break;
		}
		*(p+j+1)=t;
	}
	for(int i=0;i<m;i++)
		printf("%d\t",*(p+i));
	puts("");
	return 0;
}

三、课后作业:

实现双向链表的逆置

方法一:
DoubleLink rev_doublelink(DoubleLink L)
{
	//判断链表是否为空
	if(NULL==L)
		return L;
	//判断链表只有一个节点
	if(NULL == L || L->next==NULL)
	{
		return L;
	}
    //先找最后一个节点的位置
	DoubleLink p=L;
	while(p->next!=NULL)
	{
		p=p->next;
	}
	DoubleLink q=L;
	DoubleLink s=NULL;
	while(q!=NULL)
    {
        s=q->next;
		q->next=q->prev;
		q->prev=s;
		q=s;
    }
    return p;
}
方法二:
DoubleLink rev_doublelink(DoubleLink L)
{
	//判断链表是否为空
	if(NULL==L)
		return L;
	//判断链表只有一个节点
	if(NULL == L || L->next==NULL)
	{
		return L;
	}
	DoubleLink p=L;
	DoubleLink q=NULL;
	while (p!=NULL)
	{
		q=p->prev;
		p->prev=p->next;
		p->next=q;
		p=p->prev;
	}
	// 更新头节点的prev指针为NULL
	if(q!=NULL)
	{
		L=q->prev;
		L->prev=NULL;
	}
	return L;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值