国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列

這篇具有很好參考價(jià)值的文章主要介紹了數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

棧的概念和結(jié)構(gòu)

棧是一種常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),它遵循后進(jìn)先出LIFO(Last In First Out)的原則。進(jìn)行數(shù)據(jù)插入和操作的一端稱為棧頂,另一端稱為棧底。
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
壓棧:棧的插入操作被稱為壓棧/進(jìn)棧/入棧,入數(shù)據(jù)在棧頂。
出棧:棧的刪除操作。出數(shù)據(jù)也在棧頂;
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列

棧的實(shí)現(xiàn)

??梢杂?strong>數(shù)組或者是鏈表來(lái)實(shí)現(xiàn);這里將使用數(shù)組來(lái)實(shí)現(xiàn),因?yàn)閿?shù)組在插入刪除時(shí)消耗代價(jià)較??;對(duì)于鏈表,由于Top放在尾,刪除時(shí)還需要由頭指針循環(huán)遍歷找到尾結(jié)點(diǎn)前一個(gè);
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列

棧的數(shù)據(jù)結(jié)構(gòu)

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

a為存儲(chǔ)數(shù)據(jù)的數(shù)組,top表示棧頂,capacity表示當(dāng)前數(shù)組的存儲(chǔ)容量;

棧的初始化和銷毀

void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

void STDestory(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;

}

assert(ps)驗(yàn)證的是傳過(guò)來(lái)的地址,地址為NULL那就無(wú)法進(jìn)行操作;
free完ps->a記得置空;

出棧和入棧

void STPush(ST* ps, STDataType x)
{
	assert(ps);
	//滿擴(kuò)容
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("Stack fail");
			exit(-1);
		}
		ps->a =tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

void STPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	ps->top--;

}

這里的Top是放在最后一位元素之后的;
當(dāng)出棧時(shí),不用管那個(gè)位置的內(nèi)容和空間是否被刪除,當(dāng)下次入棧到這個(gè)位置,內(nèi)容會(huì)被頂替;而如果用free掉這一塊空間,會(huì)造成只釋放部分空間的錯(cuò)誤;

獲取棧頂、大小,判空

STDataType STTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

bool STEmpty(ST* ps)
{
	assert(ps);

	return ps->top==0;
}

對(duì)于數(shù)據(jù)結(jié)構(gòu)來(lái)說(shuō),即使是簡(jiǎn)單的操作也要用函數(shù)進(jìn)行封裝;這樣做的原因能夠找出一些錯(cuò)誤的操作,能夠方便別人的操作;
例如你在主函數(shù)創(chuàng)建的棧為空,然后給到別人使用,別人不知道棧為空,別人沒(méi)有用函數(shù)判斷棧的大小,出來(lái)的棧的大小無(wú)法辨別是對(duì)的還是錯(cuò)誤的;而創(chuàng)建函數(shù)就能夠避免一些極端問(wèn)題;

接下來(lái)我們簡(jiǎn)單的驗(yàn)證一下:

void Test1()
{
	ST st;
	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);
	
	while (!STEmpty(&st))
	{
		printf("%d ", STTop(&st));
		STPop(&st);
	}
	printf("\n");

	STDestory(&st);
}

int main()
{
	Test1();
	return 0;
}

數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列

隊(duì)列的概念和結(jié)構(gòu)

隊(duì)列只允許在一端進(jìn)行插入操作,在另一端刪除數(shù)據(jù)操作的特殊線性表,具有先進(jìn)先出FIFO(First In First Out) ;
入隊(duì)列:在隊(duì)尾進(jìn)行插入的操作
出隊(duì)列:在隊(duì)頭進(jìn)行刪除的操作
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列

隊(duì)列的實(shí)現(xiàn)

隊(duì)列的實(shí)現(xiàn)可以用數(shù)組和鏈表來(lái)實(shí)現(xiàn);這里將使用鏈表來(lái)實(shí)現(xiàn);因?yàn)槿绻褂脭?shù)組的結(jié)構(gòu),在數(shù)組頭進(jìn)行刪除出數(shù)據(jù),效率比較低;
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列

隊(duì)列的數(shù)據(jù)結(jié)構(gòu)

typedef int QDataType;
typedef struct QueneNode
{
	struct QueneNode* next;
	QDataType data;
}QNode;

typedef struct Quene
{
	QNode* head;
	QNode* tail;
	int size;
}Quene;

這里先用一個(gè)結(jié)構(gòu)體將一個(gè)結(jié)點(diǎn)的類型進(jìn)行封裝;然后再用一個(gè)結(jié)構(gòu)體進(jìn)行隊(duì)列的封裝;因?yàn)檫@里我們將會(huì)使用隊(duì)頭和隊(duì)尾,如果使用這兩個(gè)進(jìn)行傳參,將會(huì)用到二級(jí)指針,比較麻煩,所以就使用一個(gè)結(jié)構(gòu)體進(jìn)行封裝,用結(jié)構(gòu)體進(jìn)行傳參,用到隊(duì)頭和隊(duì)尾只需調(diào)用結(jié)構(gòu)體的成員;

隊(duì)列的初始化和銷毀

void QueneInit(Quene* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
void QueneDestory(Quene* 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;
}

初始化將head和tail都置空;size統(tǒng)計(jì)多少個(gè)結(jié)點(diǎn);
銷毀用循環(huán)遍歷逐漸將結(jié)點(diǎn)釋放;最后將指針置空;

隊(duì)列的插入

void QuenePush(Quene* pq, QDataType x)
{
	assert(pq);
	//擴(kuò)容
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;

	//第一個(gè)插入
	if (pq->head == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}

首先是每插入一次就擴(kuò)容一個(gè)結(jié)點(diǎn);接著是判斷是否為第一個(gè)結(jié)點(diǎn)的插入,如果是需要將head和tail都等于新節(jié)點(diǎn);最后將size加加;

隊(duì)列的刪除

void QuenePop(Quene* pq)
{
	assert(pq);
	//判斷是否沒(méi)有數(shù)據(jù)
	assert(!QueneEmpty(pq));

	QNode* next = pq->head->next;
	//只有一個(gè)數(shù)據(jù)
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = next;
	}
	else
	{
		free(pq->head);
		pq->head = next;
	}
	pq->size--;

}

我們需要判斷有沒(méi)有結(jié)點(diǎn)可以刪除;然后記住頭結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn),刪除頭結(jié)點(diǎn)后將頭結(jié)點(diǎn)指針等于下一個(gè)結(jié)點(diǎn);如果只有一個(gè)結(jié)點(diǎn)可以刪除,那么還要將tail置空;

獲取隊(duì)頭和隊(duì)尾的數(shù)據(jù)

QDataType QueneFront(Quene* pq)
{
	assert(pq);
	assert(!QueneEmpty(pq));

	return pq->head->data;
}
QDataType QueneBack(Quene* pq)
{
	assert(pq);
	assert(!QueneEmpty(pq));

	return pq->tail->data;
}

獲取隊(duì)列長(zhǎng)度和判空

int QueneSize(Quene* pq)
{
	assert(pq);
	return pq->size;
}
bool QueneEmpty(Quene* pq)
{
	assert(pq);
	return pq->head == NULL;
}

最后做一下簡(jiǎn)單的驗(yàn)證

void Test1()
{
	Quene q;
	QueneInit(&q);
	QuenePush(&q, 1);
	QuenePush(&q, 2);
	QuenePush(&q, 3);
	QuenePop(&q);
	while (QueneSize(&q)>0)
	{
		printf("%d ", QueneBack(&q));
		QuenePop(&q);
	}
	QueneDestory(&q);

}

int main()
{
	Test1();
	return 0;
}

數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列

棧和隊(duì)列的一些題目

1.有效的括號(hào)

數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列

思路:這道題可以采用棧這種結(jié)構(gòu)來(lái)解決問(wèn)題,滿足后進(jìn)先出的原理;
我們可以這么做,分為左括號(hào)和右括號(hào);遇到左括號(hào)就放入棧中,一旦遇到右括號(hào),我們可以將棧頂取出,進(jìn)行判斷;這是我們的大體思路;
這道題我們還需要考慮一些極端情況:
第一種:字符串中只有右括號(hào)或者說(shuō)一開始就是右括號(hào),那么這種就相當(dāng)于棧為空;當(dāng)遇到右括號(hào)時(shí),需要先進(jìn)行判斷;
第二種:字符串只有左括號(hào),那么表明棧中的元素沒(méi)有進(jìn)行匹配出棧,棧不為空;
所以把特殊情況弄好后,就可以進(jìn)行操作了,我們可以把我們寫的棧結(jié)構(gòu)復(fù)制到程序中,然后創(chuàng)建一個(gè)棧來(lái)進(jìn)行操作;最后記得釋放空間,避免內(nèi)存泄漏;

代碼:

#define  _CRT_SECURE_NO_WARNINGS 1

typedef char STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

void STDestory(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = 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 : ps->capacity * 2;
		STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("Stack fail");
			exit(-1);
		}
		ps->a =tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

void STPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	ps->top--;

}

STDataType STTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

bool STEmpty(ST* ps)
{
	assert(ps);

	return ps->top==0;
}

bool isValid(char * s){
    ST st;
    //棧初始化
    STInit(&st);

    while(*s)
    {
        //左括號(hào)就入棧
        if(*s=='('||*s=='['||*s=='{')
        {
            STPush(&st,*s);
        }
        //右括號(hào)就出棧,判斷
        else
        {
            ??眨砻鳑](méi)有左括號(hào)
            if(STEmpty(&st))
            {
                STDestory(&st);
                    return false;
            }
            char val=STTop(&st);
            STPop(&st);
						//不符合
            if((*s==')'&&val!='(')
            ||(*s==']'&&val!='[')
            ||(*s=='}'&&val!='{'))
            {
                return false;
            }
               
        }
        s++;
    }
    if(!STEmpty(&st))
    {
        return false;
    }
    STDestory(&st);
    return true;
}

2.用隊(duì)列實(shí)現(xiàn)棧

數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列

思路:我們可以在紙上模擬一下入棧和出棧的操作;
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
由于入棧的時(shí)候和隊(duì)列的性質(zhì)一樣,都在尾插入,所以不需要執(zhí)行什么操作;出棧時(shí),總需要進(jìn)行轉(zhuǎn)移,才能刪除最后一個(gè)元素;那么可以先判斷那個(gè)隊(duì)列空與不為空,然后將不為空的進(jìn)行轉(zhuǎn)移到空的隊(duì)列;那么就可以完成出棧;同時(shí),由于這樣的操作,入棧時(shí)如果有一個(gè)隊(duì)列不為空需要將元素插入不為空的后面,方便出棧的操作;

代碼:

#include<assert.h>
#include<stdbool.h>

typedef int QDataType;
typedef struct QueneNode
{
	struct QueneNode* next;
	QDataType data;
}QNode;

typedef struct Quene
{
	QNode* head;
	QNode* tail;
	int size;
}Quene;



void QueneInit(Quene* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
void QueneDestory(Quene* 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 QuenePush(Quene* pq, QDataType x)
{
	assert(pq);
	//擴(kuò)容
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;

	//第一個(gè)插入
	if (pq->head == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}
bool QueneEmpty(Quene* pq)
{
	assert(pq);
	return pq->head==NULL;
}
int QueneSize(Quene* pq)
{
	assert(pq);
	return pq->size;
}
void QuenePop(Quene* pq)
{
	assert(pq);
	//判斷是否沒(méi)有數(shù)據(jù)
	assert(!QueneEmpty(pq));
	
	
	//只有一個(gè)數(shù)據(jù)
	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 QueneFront(Quene* pq)
{
	assert(pq);
	assert(!QueneEmpty(pq));

		return pq->head->data;
}
QDataType QueneBack(Quene* pq)
{
	assert(pq);
	assert(!QueneEmpty(pq));

	return pq->tail->data;
}


typedef struct {
    Quene q1;
    Quene q2;
} MyStack;
//創(chuàng)建一個(gè)自己的棧

//用一個(gè)結(jié)構(gòu)體進(jìn)行包裝
MyStack* myStackCreate() {
    MyStack* obj=malloc(sizeof(MyStack));
    QueneInit(&obj->q1);
    QueneInit(&obj->q2);

    return obj;
}

//插入判斷哪個(gè)隊(duì)列不為空
void myStackPush(MyStack* obj, int x) {
    if(!QueneEmpty(&obj->q2))
    {
        QuenePush(&obj->q2,x);
    }
    else
    {
        QuenePush(&obj->q1,x);
    }
}

//將隊(duì)列分為空隊(duì)列和不空隊(duì)列
int myStackPop(MyStack* obj) {
    Quene* empty=&obj->q1;
    Quene* nonempty=&obj->q2;
    if(!QueneEmpty(&obj->q1))
    {
         empty=&obj->q2;
         nonempty=&obj->q1;
    }
	//數(shù)據(jù)轉(zhuǎn)移
    while(QueneSize(nonempty)>1)
    {
        QuenePush(empty,QueneFront(nonempty));
        QuenePop(nonempty);
    }
   //刪除數(shù)據(jù),并返回
    int Top=QueneFront(nonempty);
    QuenePop(nonempty);
    return Top;
}

int myStackTop(MyStack* obj) {
    if(!QueneEmpty(&obj->q2))
    {
        return QueneBack(&obj->q2);
    }
    else
    {
        return QueneBack(&obj->q1);
    }
}

bool myStackEmpty(MyStack* obj) {

    return QueneEmpty(&obj->q1)&&QueneEmpty(&obj->q2);
}

void myStackFree(MyStack* obj) {
    QueneDestory(&obj->q1);
    QueneDestory(&obj->q2);
    free(obj);
}

/**
 * Your MyStack struct will be instantiated and called as such:
 * MyStack* obj = myStackCreate();
 * myStackPush(obj, x);
 
 * int param_2 = myStackPop(obj);
 
 * int param_3 = myStackTop(obj);
 
 * bool param_4 = myStackEmpty(obj);
 
 * myStackFree(obj);
*/

3.用棧實(shí)現(xiàn)隊(duì)列

數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列

思路:一樣的我們先在紙上模擬
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
如果再繼續(xù)刪除,那么可以刪除到棧2為空,然后就將棧1的內(nèi)容全部轉(zhuǎn)移到棧2;如果棧2沒(méi)空,再插入棧1會(huì)發(fā)現(xiàn)沒(méi)有任何影響;
所以我們總結(jié)得出:將棧1表示為插入的棧,棧2表示為刪除的棧,如果要?jiǎng)h除棧2為空就將棧1的內(nèi)容轉(zhuǎn)移到棧2;

代碼:

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

void STDestory(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = 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 : ps->capacity * 2;
		STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("Stack fail");
			exit(-1);
		}
		ps->a =tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

void STPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	ps->top--;

}

STDataType STTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

bool STEmpty(ST* ps)
{
	assert(ps);

	return ps->top==0;
}

//棧分為插入棧和輸出棧
typedef struct {
    ST instack;
    ST outstack;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* obj=malloc(sizeof(MyQueue));
    STInit(&obj->instack);
    STInit(&obj->outstack);

    return obj;
}

void myQueuePush(MyQueue* obj, int x) {
    STPush(&obj->instack,x);
}

int myQueuePop(MyQueue* obj) {
	//先判斷輸出棧是否為空
    if(STEmpty(&obj->outstack))
    {
        while(STSize(&obj->instack))
        {
            STPush(&obj->outstack,STTop(&obj->instack));
            STPop(&obj->instack);
        }
    }
    int head=STTop(&obj->outstack);
    STPop(&obj->outstack);
    return head;
}

int myQueuePeek(MyQueue* obj) {
    if(STEmpty(&obj->outstack))
    {
        while(STSize(&obj->instack))
        {
            STPush(&obj->outstack,STTop(&obj->instack));
            STPop(&obj->instack);
        }
    }
    return STTop(&obj->outstack);
}

bool myQueueEmpty(MyQueue* obj) {
    return STEmpty(&obj->instack)&&STEmpty(&obj->outstack);
}

void myQueueFree(MyQueue* obj) {
    STDestory(&obj->instack);
    STDestory(&obj->outstack);
    free(obj);
}

/**
 * Your MyQueue struct will be instantiated and called as such:
 * MyQueue* obj = myQueueCreate();
 * myQueuePush(obj, x);
 
 * int param_2 = myQueuePop(obj);
 
 * int param_3 = myQueuePeek(obj);
 
 * bool param_4 = myQueueEmpty(obj);
 
 * myQueueFree(obj);
*/

4.設(shè)計(jì)循環(huán)隊(duì)列

數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列

我們先根據(jù)題意確定我們將選擇數(shù)組來(lái)存儲(chǔ)(固定長(zhǎng)度);然后考慮怎么讓這個(gè)數(shù)組能夠循環(huán)著走?我們可以設(shè)置兩個(gè)指針來(lái)判斷(由于是數(shù)組,可以利用下標(biāo)來(lái)進(jìn)行代表指針),分別為頭和尾;假設(shè)隊(duì)列長(zhǎng)度為k,一開始,頭和尾下標(biāo)都為0,表示這個(gè)隊(duì)列為空;
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
那么當(dāng)插入一個(gè)元素后尾向后走一步
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
刪除一個(gè)元素頭向后走一步,
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
當(dāng)數(shù)組填滿后,會(huì)發(fā)現(xiàn)頭尾又重疊在一起,與一開始隊(duì)列為空情況是一樣的,這樣就無(wú)法判斷空與滿了;
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
所以我們可以再增加一個(gè)多出來(lái)的空間
數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),開發(fā)語(yǔ)言,棧,隊(duì)列
當(dāng)尾走到最后一個(gè)多出來(lái)的空間時(shí)就表示滿;
循環(huán)的尾走到最后時(shí)我們用取模來(lái)進(jìn)行返回到下標(biāo)為0的位置;這樣子就能完成我們循環(huán)的目的。

代碼:

typedef struct {
    int* a;
    int head;
    int rear;
    int k;
    
} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj=malloc(sizeof(MyCircularQueue));
    obj->a=malloc(sizeof(int)*(k+1));
    obj->head=obj->rear=0;
    obj->k=k;
    return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->head==obj->rear;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    //當(dāng)rear超過(guò)k+1時(shí),歸0
    return (obj->rear+1)%(obj->k+1)==obj->head;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    obj->a[obj->rear]=value;
    obj->rear++;
    //限制在0-k
    obj->rear%=(obj->k+1);
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    obj->head++;
    //限制在0-k
    obj->head%=(obj->k+1);
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->a[obj->head];
}

int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    //考慮rear-1等于-1的情況
    return obj->a[(obj->rear+obj->k)%(obj->k+1)];
}

void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->a);
    free(obj);
}

/**
 * Your MyCircularQueue struct will be instantiated and called as such:
 * MyCircularQueue* obj = myCircularQueueCreate(k);
 * bool param_1 = myCircularQueueEnQueue(obj, value);
 
 * bool param_2 = myCircularQueueDeQueue(obj);
 
 * int param_3 = myCircularQueueFront(obj);
 
 * int param_4 = myCircularQueueRear(obj);
 
 * bool param_5 = myCircularQueueIsEmpty(obj);
 
 * bool param_6 = myCircularQueueIsFull(obj);
 
 * myCircularQueueFree(obj);
*/

這里需要注意的就是取模的問(wèn)題,需要記住尾和頭是不斷增加的,是由于取模k+1才限制在0-k的下標(biāo)中;
第一個(gè)就是在刪除和插入數(shù)據(jù)的時(shí)候,當(dāng)頭尾超出范圍時(shí),需要進(jìn)行取模k+1的操作,返回到第一個(gè)元素;
第二個(gè)是判斷滿時(shí),尾+1相當(dāng)于返回到頭,當(dāng)尾剛好處于最后下標(biāo)時(shí),需要進(jìn)行取模;
最后一個(gè)是取尾的問(wèn)題,當(dāng)尾剛好處于第一個(gè)下標(biāo)時(shí),由于尾需要進(jìn)行-1的操作才能得到尾元素,所欲在第一個(gè)下標(biāo)-1會(huì)導(dǎo)致下標(biāo)變?yōu)?1,所以可以多加一輪K+1進(jìn)行取模的操作避免這個(gè)問(wèn)題;文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-700043.html

到了這里,關(guān)于數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu)(C語(yǔ)言實(shí)現(xiàn))——棧和隊(duì)列的介紹及基本操作的實(shí)現(xiàn)(動(dòng)態(tài)順序棧+鏈隊(duì))

    今天我們來(lái)學(xué)習(xí)另外兩個(gè)線性結(jié)構(gòu)——棧和隊(duì)列,棧和隊(duì)列是操作受限的線性表,因此,可稱為限定性的數(shù)據(jù)結(jié)構(gòu)。 棧:一種特殊的線性表,其只允許在固定的一端進(jìn)行插入和刪除元素操作。進(jìn)行數(shù)據(jù)插入和刪除操作的一端 稱為棧頂,另一端稱為棧底。棧中的數(shù)據(jù)元素遵守

    2023年04月19日
    瀏覽(21)
  • 【數(shù)據(jù)結(jié)構(gòu)】棧和隊(duì)列(隊(duì)列篇)

    【數(shù)據(jù)結(jié)構(gòu)】棧和隊(duì)列(隊(duì)列篇)

    上期我們已經(jīng)學(xué)習(xí)了數(shù)據(jù)結(jié)構(gòu)中的棧,這期我們開始學(xué)習(xí)隊(duì)列。 目錄 1.隊(duì)列的概念及結(jié)構(gòu) 2.隊(duì)列的實(shí)現(xiàn) 隊(duì)列結(jié)構(gòu)體定義 常用接口函數(shù) 初始化隊(duì)列 隊(duì)尾入隊(duì)列 隊(duì)頭出隊(duì)列 獲取隊(duì)列頭部元素、 獲取隊(duì)列隊(duì)尾元素 獲取隊(duì)列中有效元素個(gè)數(shù) 檢測(cè)隊(duì)列是否為空 銷毀隊(duì)列 3.循環(huán)隊(duì)

    2024年02月13日
    瀏覽(24)
  • 數(shù)據(jù)結(jié)構(gòu) | 棧和隊(duì)列

    數(shù)據(jù)結(jié)構(gòu) | 棧和隊(duì)列

    … ??????本文已收錄至:數(shù)據(jù)結(jié)構(gòu) | C語(yǔ)言 更多知識(shí)盡在此專欄中! 棧(Stack) 又名堆棧,它是一種運(yùn)算受限的線性表,限定僅在表尾進(jìn)行插入和刪除操作的線性表。 隊(duì)列(Queue) 也是一種特殊的線性表,特殊之處在于它只允許在表的前端(Front)進(jìn)行刪除操作,而在表的

    2024年01月23日
    瀏覽(23)
  • [數(shù)據(jù)結(jié)構(gòu)】棧和隊(duì)列

    [數(shù)據(jù)結(jié)構(gòu)】棧和隊(duì)列

    目錄 1.棧 1.1概念 1.2 棧的使用 1.3.棧的模擬實(shí)現(xiàn) 2.隊(duì)列 2.1概念 2.2隊(duì)列的使用 2.3隊(duì)列的模擬實(shí)現(xiàn) 2.4 循環(huán)隊(duì)列 2.5雙端隊(duì)列 ? 棧:一種特殊的線性表,其只允許在固定的一端進(jìn)行插入和刪除元素操作。進(jìn)行數(shù)據(jù)插入和刪除操作的一端稱為棧頂,另一端稱為棧底。棧中的數(shù)據(jù)元素

    2024年02月07日
    瀏覽(25)
  • 數(shù)據(jù)結(jié)構(gòu):棧和隊(duì)列

    數(shù)據(jù)結(jié)構(gòu):棧和隊(duì)列

    朋友們、伙計(jì)們,我們又見(jiàn)面了,本期來(lái)給大家解讀一下棧和隊(duì)列方面的相關(guān)知識(shí)點(diǎn),如果看完之后對(duì)你有一定的啟發(fā),那么請(qǐng)留下你的三連,祝大家心想事成! C 語(yǔ) 言 專 欄:C語(yǔ)言:從入門到精通 數(shù)據(jù)結(jié)構(gòu)專欄:數(shù)據(jù)結(jié)構(gòu) 個(gè) 人 主 頁(yè) :??stackY、 目錄 前言:? 1.棧 1.1棧的

    2024年02月06日
    瀏覽(24)
  • 數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列

    數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列

    棧是一種常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),它遵循 后進(jìn)先出LIFO (Last In First Out)的原則。 進(jìn)行數(shù)據(jù)插入和操作的一端稱為棧頂,另一端稱為棧底 。 壓棧 :棧的插入操作被稱為壓棧/進(jìn)棧/入棧,入數(shù)據(jù)在棧頂。 出棧 :棧的刪除操作。出數(shù)據(jù)也在棧頂; 棧可以用 數(shù)組 或者是 鏈表 來(lái)實(shí)現(xiàn);

    2024年02月09日
    瀏覽(27)
  • 數(shù)據(jù)結(jié)構(gòu)---棧和隊(duì)列

    棧:一種特殊的線性表,其只允許在固定的一端進(jìn)行插入和刪除元素操作,進(jìn)行數(shù)據(jù)插入和刪除操作的一端稱為棧頂,另一端稱為棧底。棧中的數(shù)據(jù)元素遵守后進(jìn)先出LIFO(Last In First Out)的原則。 壓棧:棧的插入操作叫做進(jìn)棧/壓棧/入棧,入數(shù)據(jù)在棧頂。 出棧:棧的刪除操作

    2024年01月18日
    瀏覽(35)
  • 數(shù)據(jù)結(jié)構(gòu)——棧和隊(duì)列

    數(shù)據(jù)結(jié)構(gòu)——棧和隊(duì)列

    目錄 ?一.前言 二.前文回顧 三.棧 3.1 棧的概念及結(jié)構(gòu) 3.2 棧的實(shí)現(xiàn) 3.2.1 初始化函數(shù) 3.2.2 銷毀函數(shù) 3.2.3 入棧函數(shù) 3.2.4 出棧函數(shù) 3.2.5 計(jì)算大小函數(shù) 3.2.6 空棧函數(shù) 3.2.7 獲取棧頂函數(shù) ?3.2.8 小測(cè)試 3.3 全部代碼 四.棧的練習(xí) 4.1 有效的括號(hào) 五.隊(duì)列 5.1隊(duì)列的概念及結(jié)構(gòu) 5.2 隊(duì)列的實(shí)

    2024年01月25日
    瀏覽(22)
  • 棧和隊(duì)列【數(shù)據(jù)結(jié)構(gòu)】
  • 數(shù)據(jù)結(jié)構(gòu)【棧和隊(duì)列】

    數(shù)據(jù)結(jié)構(gòu)【棧和隊(duì)列】

    一、棧 1.定義:只允許一端進(jìn)行插入和刪除的線性表,結(jié)構(gòu)與手槍的彈夾差不多,可以作為實(shí)現(xiàn)遞歸函數(shù)(調(diào)用和返回都是后進(jìn)先出)調(diào)用的一種數(shù)據(jù)結(jié)構(gòu); 棧頂:允許插入刪除的那端; 棧底:固定的,不允許插入或刪除; 空棧:不含元素; 2.特點(diǎn):后進(jìn)先出; 3.操作:入

    2024年02月15日
    瀏覽(28)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包