序言
前面一篇博客介绍了链表的常用功能,算做链表的基本训练,链表尤其擅长在内存的动态分配,有序数列的增删方面,此外链表常常也配合栈空间试用。
需求
本篇实现一个栈结构,完成数据的入栈和出栈,并返回栈中最大值(复杂度为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)