栈_单向链表

利用单向链表设计一个栈,实现“后进先出”的功能

​ 栈内存自顶向下进行递增,其实栈和顺序表以及链式表都一样,都属于线性结构,存储的数据的逻辑关系也是一对一的。

​ 栈的一端是封闭的,数据的插入与删除只能在栈的另一端进行,也就是栈遵循“*后进先出*”的原则。也被成为“LIFO”结构,意思是“last input first output”。

闭合的一端被称为栈底(Stack Bottom),允许数据的插入与删除的一端被称为栈顶(Stack Top),不包含任何元素的栈被称为空栈。

  • l 把数据插入到栈空间的动作被称为入栈或者压栈,英文Push)
  • l 从栈空间中删除数据的动作被称为出栈或者弹栈,英文Pop)

程序结构思路:

​ 根据链表在头部增删比较简单的特性。将单向链表的首结点当作栈顶,尾结点当作粘底,入栈相当于头插操作,出栈相当于头删操作。

程序实现:

/********************************************************************************************
*   file name: StackLList.c
*   author   : liaojx2016@126.com
*   date     : 2024/04/25
*   function : Design stack interface to achieve “last input first output”
*   note     : None
*
*   CopyRight (c)  2023-2024   liaojx2016@126.com   All Right Reseverd 
*
*********************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<stdlib.h>
//指的是单向链表中的结点有效数据类型,用户可以根据需要进行修改
typedef int  DataType_t;

//构造链表的结点,链表中所有结点的数据类型应该是相同的
typedef struct StackLinkedList
{
	DataType_t  		 data; //结点的数据域
	struct StackLinkedList	*next; //结点的指针域

}QueueLList_t;

/**********************************************************************************************
*   func name       : QueueLList_Create
*   function        : Create a empty stack link list to store hexadecimal digit
*   func parameter  : None
*   return resuolt  : Address of head node
*   author          : liaojx2016@126.com
*   date            : 2024/04/25
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//创建一个空链表,空链表应该有一个头结点,对链表进行初始化
QueueLList_t * QueueLList_Create(void)
{
	//1.创建一个头结点并对头结点申请内存
	QueueLList_t *Head = (QueueLList_t *)calloc(1,sizeof(QueueLList_t));
	if (NULL == Head)
	{
		perror("Calloc memory for Head is Failed");
		exit(-1);
	}

	//2.对头结点进行初始化,头结点是不存储有效内容的!!!
	Head->next = NULL;

	//3.把头结点的地址返回即可
	return Head;
}
/**********************************************************************************************
*   func name       : StackLList_NewNode
*   function        : Create a new node and do initialization
*   func parameter  : 
*                       @data :address of head node 
*   return resuolt  : Address of a new node
*   author          : liaojx2016@126.com
*   date            : 2024/04/25
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//创建新的结点,并对新结点进行初始化(数据域 + 指针域)
QueueLList_t * QueueLList_NewNode(DataType_t data)
{
	//1.创建一个新结点并对新结点申请内存
	QueueLList_t *New = (QueueLList_t *)calloc(1,sizeof(QueueLList_t));
	if (NULL == New)
	{
		perror("Calloc memory for NewNode is Failed");
		return NULL;
	}

	//2.对新结点的数据域和指针域进行初始化
	New->data = data;
	New->next = NULL;

	return New;
}
/**********************************************************************************************
*   func name       : StackLList_Push
*   function        : Do stack push action
*   func parameter  : 
*                       @Head :address of head node 
                        @data :Disposed remainder
*   return resuolt  : Stack push success result (true or false)
*   author          : liaojx2016@126.com
*   date            : 2024/04/25
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//头插
bool StackLList_Push(QueueLList_t *Head,DataType_t data)

{
	//1.创建新的结点,并对新结点进行初始化
	QueueLList_t *New = QueueLList_NewNode(data);
	if (NULL == New)
	{
		printf("can not insert new node\n");
		return false;
	}
	//2.判断链表是否为空,如果为空,则直接插入即可
	if (NULL == Head->next)
	{
		Head->next = New;
		return true;
	}

	//3.如果链表为非空,则把新结点插入到链表的头部
	New->next  = Head->next;    //新结点的next指针指向原首结点
	Head->next = New;           //头结点的next指针指向新结点

	return true;
}
/**********************************************************************************************
*   func name       : StackLList_Pop
*   function        : Stack pop for one node
*   func parameter  : 
*                       @Head :address of head node 
*   return resuolt  : Stack pop success result (true or false)
*   author          : liaojx2016@126.com
*   date            : 2024/04/25
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//头删
bool StackLList_Pop(QueueLList_t *Head)
{
    //当链表为空,删除失败,返回false
    if (NULL == Head->next)
	{
		printf("Stack linklist is empty,headdelete failed\n");
		return false;
	}
    QueueLList_t *Delnode=Head->next;   //备份首结点
    //printf("next=%#x\n",Head->next->next);
    //输出出栈的数据
    printf("the push element data is %d\n",Head->next->data);
    //删除出栈结点
    Head->next=Head->next->next;    //头结点的next指针指向首结点的直接后继
    Delnode->next=NULL;             //原首结点指向NULL,防止内存泄漏
    free(Delnode);                  //释放内存
    return true;
}
/**********************************************************************************************
*   func name       : QueueLList_Print
*   function        : Stack data print
*   func parameter  : 
*                       @Head :address of head node 
*   return resuolt  : Print success result (true or false)
*   author          : liaojx2016@126.com
*   date            : 2024/04/25
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//遍历
bool QueueLList_Print(QueueLList_t *Head)
{
    if (Head->next==NULL)   {
        printf("stack link list is empty\n");
        return false;
    }
	//对链表的头文件的地址进行备份
	QueueLList_t *Phead = Head;
	printf("the Stack linkedlist data is \n");
    //遍历结点,输出数据
	do
	{
		//把头的直接后继作为新的头结点
		Phead = Phead->next;
		//输出头结点的直接后继的数据域
		printf("%d ",Phead->data);
	}
	while(Phead->next);
    printf("\n");
    return true;
}
//
int main(int argc, char const *argv[])
{
	QueueLList_t *head=QueueLList_Create();
    //StackLList_Push 入栈操作,StackLList_Pop 出栈操作,QueueLList_Print 栈遍历输出
    StackLList_Push(head,0);
    QueueLList_Print(head);
    StackLList_Pop(head);
    QueueLList_Print(head);
    StackLList_Push(head,1);
    StackLList_Push(head,6);
    StackLList_Push(head,4);
    QueueLList_Print(head);
    StackLList_Pop(head);
    QueueLList_Print(head);

	return 0;
}

测试输出结果:
image

posted @ 2024-05-01 13:23  沉舟道人  阅读(8)  评论(0编辑  收藏  举报