[C语言] 双向链表,栈空间训练实例

序言

前面一篇博客介绍了链表的常用功能,算做链表的基本训练,链表尤其擅长在内存的动态分配,有序数列的增删方面,此外链表常常也配合栈空间试用。

需求

本篇实现一个栈结构,完成数据的入栈和出栈,并返回栈中最大值(复杂度为1).

实现思路

返回最大值复杂度为1,则要求入栈或者出栈后,最大值基于数据结构就一定是已知的。

那么入栈出栈时,维护好一个有序的双向链表,最大值位于尾结点即可。

栈结构还是用数组,找最大值时到对应的有序链表上找出即可。

即数组保持入栈出栈顺序,链表记录栈空间中数据的有序序列。

当然数组的动态内存分配,配合单向链表,遍历及处理结点就够了,双向链表,可能更新链接麻烦,遍历还得用循环。

注意:链表很多访问是基于指针,需要谨慎,如果请求内核空间,会导致程序挂掉。

双向链表图

 

代码实现:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define stack_capacity 6

struct ListNode {
	int val;
	struct ListNode *before;
	struct ListNode *next;
};

struct stack {
	struct ListNode *head;
	struct ListNode *last;
	int capacity;
	int size;
};

pushstack(int array[],int val,struct stack *older_head)
{
	struct ListNode *templist=(struct ListNode *) malloc(sizeof(struct ListNode));
	struct ListNode *temppoint=NULL;
	templist->val=val;
	array[older_head->size]=val;

	if (older_head->head==NULL)/*栈的链表为空*/
	{
		templist->before=NULL;
		templist->next=NULL;
		older_head->head=templist;
		older_head->last=templist;
	} else /*栈的链表非空,将结点插入合适位置*/
	{
		if (templist->val <= older_head->head->val)/*入栈数据最小,置于首结点*/
		{
			templist->before=NULL;
			templist->next=older_head->head;
			older_head->head=templist;
			older_head->last->before=templist;
		} else if (templist->val >= older_head->last->val)/*入栈数据最大,置于尾结点*/
		{
			templist->next=NULL;
			templist->before=older_head->last;
			older_head->last->next=templist;
			older_head->last=templist;
		} else /*入栈数据介于首尾结点中间,置于中间结点*/
		{
			temppoint=older_head->head;
			while (1)
			{
				if (temppoint->val <= templist->val <= temppoint->next->val)
				{
					templist->before=temppoint;
					templist->next=temppoint->next;
					temppoint->next->before=templist;/*在下一个结点未改变时,更改其前结点*/
					temppoint->next=templist;
					break;
				}
				temppoint=temppoint->next;
			}
		}
	}
	older_head->size++;
	
	int i;
	printf("stack as : ");
	for (i=0;i<older_head->size;i++)
	{
		printf("%d ",array[i]);
	}
	printf("max value is %d\n",older_head->last->val);
}

popstack(int array[],struct stack *older_head)
{
	/*首、尾、中间结点出栈*/
	struct ListNode *temp=NULL;
	if (older_head->size==1)/*唯一结点*/
	{
		temp=older_head->head;
		free(temp);
	}
	else if (older_head->head->val == array[older_head->size-1])/*首结点出栈*/
	{
		temp=older_head->head;
		temp->next->before=NULL;
		older_head->head=temp->next;
		free(temp);
	} else if (older_head->last->val == array[older_head->size-1])/*尾结点出栈*/
	{
		temp=older_head->last;
		temp->before->next=NULL;
		older_head->last=temp->before;
		free(temp);
	} else /*中间结点出栈*/
	{
		temp=older_head->head->next;
		while(1)
		{
			if (temp->val == array[older_head->size-1])
			{
				temp->before->next=temp->next;
				temp->next->before=temp->before;
				free(temp);
				break;
			} else 
			{
				temp=temp->next;
			}
		}
	}
	older_head->size--;

	int i;
	printf("stack as: ");
	for (i=0;i<older_head->size;i++)
	{
		printf("%d ",array[i]);
	}
	if (older_head->size>=1)
	{
		printf("max value in stack is %d\n",older_head->last->val);
	} else 
	{
		printf("stack space is empty from now\n");
	}
}

int main(void)
{
	/*栈空间最好初始化,只给一个指针的化,栈结构体变量要malloc,链表结点也要malloc一次;
	  链表可以不用初始化,只给一个指针,每次结点都malloc,然后挂载上来。*/
	char direct;
	int temp;
	int stackarray[stack_capacity]={0};
	struct stack Ordered_stack={NULL,NULL,stack_capacity,0};/*有序栈*/
	int test[6] = {1,4,6,3,7,5};
	while (1)
	{
		printf("Please input directiong(+ rep push,- rep pop)\n");
		scanf("%c",&direct);
		getchar();
		if (direct=='+')
		{
			if (Ordered_stack.size==Ordered_stack.capacity)
			{
				printf("The stack space is full and can no longer accept the push request.\n");
				continue;
			}
			printf("Please input the value will be push\n");
			scanf("%d",&temp);
			getchar();
			//temp=test[Ordered_stack.size];
			pushstack(stackarray,temp,&Ordered_stack);
		} else if (direct=='-') 
		{
			if (Ordered_stack.size==0)
			{
				printf("The stack space is empty and can no longer accept the pop request.\n");
				continue;
			}
			popstack(stackarray,&Ordered_stack);
		} else {
			printf("direction is invalid!\n");
		}
	}
	
	return 0;

}

测试集:

E:\Develop\stack>stack.exe
Please input directiong(+ rep push,- rep pop)
+
Please input the value will be push
1
stack as : 1 max value is 1
Please input directiong(+ rep push,- rep pop)
+
Please input the value will be push
3
stack as : 1 3 max value is 3
Please input directiong(+ rep push,- rep pop)
+
Please input the value will be push
5
stack as : 1 3 5 max value is 5
Please input directiong(+ rep push,- rep pop)
+
Please input the value will be push
4
stack as : 1 3 5 4 max value is 5
Please input directiong(+ rep push,- rep pop)
+
Please input the value will be push
2
stack as : 1 3 5 4 2 max value is 5
Please input directiong(+ rep push,- rep pop)
+
Please input the value will be push
6
stack as : 1 3 5 4 2 6 max value is 6
Please input directiong(+ rep push,- rep pop)
+
The stack space is full and can no longer accept the push request.
Please input directiong(+ rep push,- rep pop)
-
stack as: 1 3 5 4 2 max value in stack is 5
Please input directiong(+ rep push,- rep pop)
-
stack as: 1 3 5 4 max value in stack is 5
Please input directiong(+ rep push,- rep pop)
-
stack as: 1 3 5 max value in stack is 5
Please input directiong(+ rep push,- rep pop)
-
stack as: 1 3 max value in stack is 3
Please input directiong(+ rep push,- rep pop)
-
stack as: 1 max value in stack is 1
Please input directiong(+ rep push,- rep pop)
-
stack as: stack space is empty from now
Please input directiong(+ rep push,- rep pop)
-
The stack space is empty and can no longer accept the pop request.
Please input directiong(+ rep push,- rep pop)
+
Please input the value will be push
1
stack as : 1 max value is 1
Please input directiong(+ rep push,- rep pop)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值