数据结构栈和队列的实现。

本文详细介绍了如何使用C/C++实现栈和队列的结构及操作函数,包括初始化、销毁、插入、删除、判空、获取元素个数和头部/顶部数据等,提供完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一,结构

1.栈结构

2.队列结构

二,函数接口

1.栈的函数接口

2.队列的函数接口

三,函数接口的实现

1.栈的接口实现

(1) 初始化

(2)销毁

(3)插入数据

(4)删除数据

(5)判空

(6)返回栈元素个数

(7)返回栈顶数据

2.队列的接口实现

(1)初始化队列

(2)销毁队列

(3)插入数据

(4)删除数据

(5)判空

(6)返回队列元素个数

(7)返回队头数据

(8)返回队尾数据

三,代码链接


一,结构

1.栈结构

typedef char DataType;
typedef struct StackNode
{
	DataType* data;
	size_t top;   //记录栈顶的后一个位置,如果初始化位0的话。
	size_t capacity;   //记录栈的容量。

}ST;

这里的数据类型可以动过改变typedef  中的char 来进行改变。

2.队列结构

//选择用单链表结构来实现队列
typedef int QDataType;
typedef struct	QueueNode
{
	QDataType data;
	struct	QueueNode* next;

}QueueNode;


//队列结构,在队列尾插入,在队列头部删除。头->->->->=NULL;  实现先插入,先取出。先进先出的特性。
typedef struct Queue
{
	QueueNode* tail;
	QueueNode* head;
	//size_t size;  如果要实现size接口不想遍历O(N)的话,可以在加一个参数。
}Queue;

二,函数接口

栈的队列的接口其实时差不多的,大差不差的。

1.栈的函数接口

void StackInit(ST* ps);                            //初始化
void StackDestory(ST* ps);                     //销毁
void StackPush(ST* ps, DataType x);     //插入数据
void StackPop(ST* ps);                           //删除数据
bool StackEmpty(ST* ps);                       //判断栈是否为空
int StackSize(ST* ps);                             //返回队列中数据个数
DataType StackTop (ST* ps);                 //返回栈顶数据

2.队列的函数接口

//想改变这个结构体,那就要传结构体的指针。
void QueueInit(Queue* pq);                                //初始化队列
void QueueDestory(Queue* pq);                         //销毁队列 
void QueuePush(Queue* pq, QDataType x);       //插入数据
void QueuePop(Queue* pq);                                //删除数据
bool QueueEmpty(Queue* pq);                            //判空
size_t QueueSize(Queue* pq);                             //返回队列中元素个数
QDataType QueueFront(Queue* pq);                  //取队头数据
QDataType QueueBack(Queue* pq);                    //取队尾数据

三,函数接口的实现

1.栈的接口实现

(1) 初始化

void StackInit(ST* ps)
{
    assert(ps);
    ps->capacity = 0;
    ps->top = 0; //这里初始化位0.那么yop代表栈顶元素的下一个位置。
    ps->data = NULL;

}

(2)销毁


void StackDestory(ST* ps)
{
    assert(ps);
    free(ps->data);
    ps->capacity = 0;
    ps->top = 0;
    ps->data = NULL;
}

(3)插入数据


void StackPush(ST* ps, DataType x)
{
    assert(ps);
    if (ps->capacity == ps->top)
    {
        //需要扩容:
        size_t newlen = ps->capacity == 0 ? 4 : ps->capacity * 2;
        DataType* tmp = (DataType*)realloc(ps->data,sizeof(DataType) * newlen);
        //if (ps->data == NULL)
        //{
        //    printf("malloc fail\n");
        //    exit(-1);
        //}
        //走到这里那就是开空间成功了。
        if(tmp==NULL)
        { 
        }
        else
        {
            ps->data = tmp;
            ps->capacity = newlen;
        }
    }

    ps->data[ps->top++] = x;

}

(4)删除数据


void StackPop(ST* ps)
{
    assert(ps);
    --ps->top;
}

(5)判空


bool StackEmpty(ST* ps)
{
    assert(ps);
    return ps->top == 0;
}

(6)返回栈元素个数


int StackSize(ST* ps)
{
    assert(ps);
    return ps->top;
}

(7)返回栈顶数据


DataType StackTop(ST* ps)
{
    assert(ps);
    //assert(ps->top > 0);   t多余,我们这里用的是size_t
    return ps->data[ps->top - 1];
}

2.队列的接口实现

(1)初始化队列

void QueueInit(Queue* pq)
{
    assert(pq);
    pq->head = pq->tail = NULL;

}

(2)销毁队列


void QueueDestory(Queue* pq)
{
    assert(pq);
    QueueNode* head = pq->head;
    while (head)
    {
        QueueNode* next = head->next;
        free(head);
        head = next;
    }
    //释放完一点要记得置NULL;
    pq->head = pq->tail = NULL;
}

(3)插入数据


void QueuePush(Queue* pq, QDataType x)
{
    assert(pq);
    QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
    if (newnode == NULL)
    {
        printf("malloc fail\n");
        exit(-1);
    }

    if (pq->tail == NULL)
    {
        assert(pq->head == NULL);
        pq->head = pq->tail = newnode;
    }
    else
    {
        pq->tail->next = newnode;
        //链接起来之后,一点不要忘记更新尾。
        pq->tail = newnode;
    }
    //这俩句放到前面更好一点,不容易忘记。
    newnode->data = x;
    newnode->next = NULL;
}

(4)删除数据


void QueuePop(Queue* pq)
{
    //实现头删就ok了
    assert(pq);
    assert(pq->head && pq->tail);
    //考虑的不完善哦。   因为这里如果只有一个的话,删除完之后,tail没有被置NULL,再次插入就会发生野指针的问题。
    //QueueNode* next = pq->head->next;
    //free(pq->head);
    //pq->head = next;
    if (pq->head->next == NULL)
    {
        free(pq->head);
        pq->head = pq->tail = NULL;
    }
    else
    {
        QueueNode* next = pq->head->next;
        free(pq->head);
        pq->head = next;
    }

}

(5)判空


bool QueueEmpty(Queue* pq)
{
    assert(pq);
    //return pq->head == NULL && pq->head == NULL;  没必要。

    return pq->tail == NULL;

}

(6)返回队列元素个数


size_t QueueSize(Queue* pq)
{
    assert(pq);
    QueueNode* cur = pq->head;
    size_t n = 0;
    while (cur)
    {
        n++;
        cur = cur->next;
    }
    return n;
}

(7)返回队头数据


QDataType QueueFront(Queue* pq)
{
    assert(pq);
    assert(pq->head);
    return pq->head->data;
}

(8)返回队尾数据


QDataType QueueBack(Queue* pq)
{
    assert(pq);
    assert(pq->tail);
    return pq->tail->data;
}

三,代码链接

data structure: 数据解构练习 - Gitee.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LYH_1_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值