一、棧
1.棧的概念及結構
(1)棧的概念
棧是一種特殊的線性表,其只允許在固定的一端進行插入和刪除元素操作。進行數(shù)據插入和刪除操作的一端稱為棧頂,另一端稱為棧底。棧中的數(shù)據元素遵守后進先出LIFO(Last In First Out)的原則。
壓棧:棧的插入操作叫做進棧/壓棧/入棧,入數(shù)據在棧頂。
出棧:棧的刪除操作叫做出棧。出數(shù)據也在棧頂。
(2)棧的結構
2.棧的實現(xiàn)
(1)類型和函數(shù)的聲明
棧的結構與順序表相同,也是用數(shù)組。因為棧的特點是出棧、入棧在同一位置,所以用數(shù)組尾插更方便。
typedef int STDataType;
typedef struct Stack
{
STDataType* data;
int top;
int capacity;
}ST;
//初始化
void STInit(ST* ps);
//銷毀
void STDestroy(ST* ps);
//入棧
void STPush(ST* ps, STDataType x);
//出棧
void STPop(ST* ps);
//檢查是否為空
bool STEmpty(ST* ps);
//獲取棧的元素個數(shù)
int STSize(ST* ps);
//獲取棧頂元素
STDataType STTop(ST* ps);
(2)初始化棧
void STInit(ST* ps)
{
assert(ps);
ps->data = NULL;
ps->capacity = 0;
ps->top = 0;
}
(3)銷毀
void STDestroy(ST* ps)
{
assert(ps);
free(ps->data);
ps->data = NULL;
ps->capacity = 0;
ps->top = 0;
}
(4)入棧
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* tmp = (STDataType*)realloc(ps->data, sizeof(STDataType) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->data = tmp;
ps->capacity = newcapacity;
}
ps->data[ps->top] = x;
ps->top++;
}
(5)出棧
void STPop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
ps->top--;
}
(6)檢查是否為空
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
(7)獲取棧的元素個數(shù)
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
(8)獲取棧頂元素
STDataType STTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->data[ps->top - 1];
}
二、棧的全部代碼
1.Stack.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int STDataType;
typedef struct Stack
{
STDataType* data;
int top;
int capacity;
}ST;
//初始化
void STInit(ST* ps);
//銷毀
void STDestroy(ST* ps);
//入棧
void STPush(ST* ps, STDataType x);
//出棧
void STPop(ST* ps);
//檢查是否為空
bool STEmpty(ST* ps);
//獲取棧的元素個數(shù)
int STSize(ST* ps);
//獲取棧頂元素
STDataType STTop(ST* ps);
2Stack.c
#include "Stack.h"
//初始化
void STInit(ST* ps)
{
assert(ps);
ps->data = NULL;
ps->capacity = 0;
ps->top = 0;
}
//銷毀
void STDestroy(ST* ps)
{
assert(ps);
free(ps->data);
ps->data = NULL;
ps->capacity = 0;
ps->top = 0;
}
//入棧
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* tmp = (STDataType*)realloc(ps->data, sizeof(STDataType) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->data = tmp;
ps->capacity = newcapacity;
}
ps->data[ps->top] = x;
ps->top++;
}
//出棧
void STPop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
ps->top--;
}
//檢查是否為空
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
//獲取棧的元素個數(shù)
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
//獲取棧頂元素
STDataType STTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->data[ps->top - 1];
}
3.Test.c
#include "Stack.h"
void test()
{
ST st;
STInit(&st);
STPush(&st, 1);
STPush(&st, 2);
STPush(&st, 3);
STPush(&st, 4);
STPush(&st, 5);
while (!STEmpty(&st))
{
printf("%d ", STTop(&st));
STPop(&st);
}
STDestroy(&st);
}
int main()
{
test();
return 0;
}
三、隊列
1.隊列的概念及結構
(1)隊列的概念
隊列:只允許在一端進行插入數(shù)據操作,在另一端進行刪除數(shù)據操作的特殊線性表,隊列具有先進先出FIFO(First In First Out) 入隊列:進行插入操作的一端稱為隊尾 出隊列:進行刪除操作的一端稱為隊頭
(2)隊列的結構
2.隊列的實現(xiàn)
隊列也可以數(shù)組和鏈表的結構實現(xiàn),使用鏈表的結構實現(xiàn)更優(yōu)一些,因為如果使用數(shù)組的結構,出隊列在數(shù)組頭上出數(shù)據,效率會比較低。
(1)類型和函數(shù)的聲明
隊列除了節(jié)點的結構體以外,還要再創(chuàng)建一個結構體,方便找到尾指針。
typedef int QDataType;
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;
}Que;
//初始化
void QueInit(Que* pq);
//銷毀
void QueDestroy(Que* pq);
//入隊
void QuePush(Que* pq, QDataType x);
//出隊
void QuePop(Que* pq);
//獲取頭部元素
QDataType QueFront(Que* pq);
//獲取隊尾元素
QDataType QueBack(Que* pq);
//獲取元素個數(shù)
int QueSize(Que* pq);
//檢查是否為空
bool QueEmpty(Que* pq);
(2)初始化隊列
void QueInit(Que* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
pq->size = 0;
}
(3)銷毀
void QueDestroy(Que* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
(4)入隊
入隊相當于尾插,因為只有一個入口插入節(jié)點,所以直接在這個函數(shù)創(chuàng)建一個新節(jié)點。分兩種情況:剛開始沒有節(jié)點尾插、已有節(jié)點再尾插。
void QuePush(Que* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
if (pq->tail == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
(5)出隊
出隊相當于頭刪。如果沒有節(jié)點,就不能再刪了,所以要斷言檢查是否為空。這里的頭刪也要分兩種情況:只有一個節(jié)點、一個以上的節(jié)點。文章來源:http://www.zghlxwxcb.cn/news/detail-668855.html
void QuePop(Que* pq)
{
assert(pq);
assert(!QueEmpty(pq));
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
pq->size--;
}
(6)獲取頭部元素
QDataType QueFront(Que* pq)
{
assert(pq);
assert(!QueEmpty(pq));
return pq->head->data;
}
(7)獲取隊尾元素
QDataType QueBack(Que* pq)
{
assert(pq);
assert(!QueEmpty(pq));
return pq->tail->data;
}
(8)獲取元素個數(shù)
int QueSize(Que* pq)
{
assert(pq);
return pq->size;
}
(9)檢查是否為空
bool QueEmpty(Que* pq)
{
assert(pq);
return pq->head == NULL;
}
四、隊列的全部代碼
1.Queue.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int QDataType;
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;
}Que;
//初始化
void QueInit(Que* pq);
//銷毀
void QueDestroy(Que* pq);
//入隊
void QuePush(Que* pq, QDataType x);
//出隊
void QuePop(Que* pq);
//獲取頭部元素
QDataType QueFront(Que* pq);
//獲取隊尾元素
QDataType QueBack(Que* pq);
//獲取元素個數(shù)
int QueSize(Que* pq);
//檢查是否為空
bool QueEmpty(Que* pq);
2.Queue.c
#include "Queue.h"
//初始化
void QueInit(Que* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
pq->size = 0;
}
//銷毀
void QueDestroy(Que* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
//入隊
void QuePush(Que* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
if (pq->tail == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
//出隊
void QuePop(Que* pq)
{
assert(pq);
assert(!QueEmpty(pq));
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
pq->size--;
}
//獲取頭部元素
QDataType QueFront(Que* pq)
{
assert(pq);
assert(!QueEmpty(pq));
return pq->head->data;
}
//獲取隊尾元素
QDataType QueBack(Que* pq)
{
assert(pq);
assert(!QueEmpty(pq));
return pq->tail->data;
}
//獲取元素個數(shù)
int QueSize(Que* pq)
{
assert(pq);
return pq->size;
}
//檢查是否為空
bool QueEmpty(Que* pq)
{
assert(pq);
return pq->head == NULL;
}
3.Test.c
#include "Queue.h"
void test()
{
Que q;
QueInit(&q);
QuePush(&q, 1);
QuePush(&q, 2);
QuePush(&q, 3);
QuePush(&q, 4);
QuePush(&q, 5);
while (!QueEmpty(&q))
{
printf("%d ", QueFront(&q));
QuePop(&q);
}
printf("\n");
QueDestroy(&q);
}
int main()
{
test();
return 0;
}
感謝觀看~文章來源地址http://www.zghlxwxcb.cn/news/detail-668855.html
到了這里,關于【數(shù)據結構】實現(xiàn)棧和隊列的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!