文章目錄
- 設計回圈佇列
- 題目
- 陣列形式(通過下標控制來達到回圈的效果)
- 環隊結構體(陣列)
- 環隊初始化
- 判斷環隊為空
- 判斷環隊為滿
- 環隊入資料并入成功回傳真
- 環隊刪資料并刪成功回傳真
- 環隊取隊頭資料(對慷訓傳-1)
- 環隊取隊尾資料(對慷訓傳-1)
- 環隊銷毀
- 環隊(陣列實作)
- 鏈表形式
- 環隊結構體(鏈表)
- 環隊初始化
- 判斷環隊為空
- 判斷環隊為滿
- 環隊入資料并入成功回傳真
- 環隊刪資料并刪成功回傳真
- 環隊取隊頭資料(對慷訓傳-1)
- 環隊取隊尾資料(對慷訓傳-1)
- 環隊銷毀
- 環隊(鏈表實作)
- 實際上這題我報錯我不想找了太惡心了(家凌幫我找錯的非常感謝)
設計回圈佇列
題目

我們會使用一種佇列叫回圈佇列,如作業系統課程講解生產者消費者模型時可以就會使用回圈佇列,環形佇列可以使用陣列實作,也可以使用回圈鏈表實作,


可以認為隊尾tail不是隊尾,而是我們認知上隊尾的后一個
陣列形式(通過下標控制來達到回圈的效果)

環隊結構體(陣列)
typedef struct {
int* a;
int front;
int tail;
int k;//陣列元素(佇列長度)
} MyCircularQueue;
環隊初始化
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
q->a = (int*)malloc(sizeof(int)*(k+1));//佇列長度為k我們要多開一個
q->front = q->tail = 0;
q->k = k;
return q;
}
判斷環隊為空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->front == obj->tail;
}
判斷環隊為滿
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->tail+1)%(obj->k+1) == obj->front;
}
環隊入資料并入成功回傳真
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(!myCircularQueueIsFull(obj))
{
obj->a[obj->tail] = value;//不是隊滿就下標tail的資料為value
obj->tail++;
obj->tail %= obj->k+1;//tail就步進一位
return true;
}
return false;//隊滿就插不進去了
}
環隊刪資料并刪成功回傳真
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(!myCircularQueueIsEmpty(obj))
{
obj->front++;//隊不空就是出隊,頭標步進就行了
obj->front %= obj->k+1;
return true;
}
return false;//對空就刪不了了
}
環隊取隊頭資料(對慷訓傳-1)
int myCircularQueueFront(MyCircularQueue* obj) {
if(!myCircularQueueIsEmpty(obj))
{
return obj->a[obj->front]; //取front位置的資料就行
}
return -1;
}
環隊取隊尾資料(對慷訓傳-1)
int myCircularQueueRear(MyCircularQueue* obj) {
if(!myCircularQueueIsEmpty(obj))
{
return obj->a[obj->tail == 0 ? obj->k : obj->tail-1];//取tail前一個資料就行,tail為0,前一個就是k位置資料
}
return -1;
}
環隊銷毀
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
obj->a = NULL;
obj->front = 0;
obj->tail = 0;
obj->k = 0;
free(obj);
}


環隊(陣列實作)
typedef struct {
int* a;
int front;
int tail;
int k;//陣列元素(佇列長度)
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
q->a = (int*)malloc(sizeof(int)*(k+1));//佇列長度為k我們要多開一個
q->front = q->tail = 0;
q->k = k;
return q;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(!myCircularQueueIsFull(obj))
{
obj->a[obj->tail] = value;//不是隊滿就下標tail的資料為value
obj->tail++;
obj->tail %= obj->k+1;//tail就步進一位
return true;
}
return false;//隊滿就插不進去了
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(!myCircularQueueIsEmpty(obj))
{
obj->front++;//隊不空就是出隊,頭標步進就行了
obj->front %= obj->k+1;
return true;
}
return false;//對空就刪不了了
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(!myCircularQueueIsEmpty(obj))
{
return obj->a[obj->front]; //取front位置的資料就行
}
return -1;
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(!myCircularQueueIsEmpty(obj))
{
return obj->a[obj->tail == 0 ? obj->k : obj->tail-1];//取tail前一個資料就行,tail為0,前一個就是k位置資料
}
return -1;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->front == obj->tail;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->tail+1)%(obj->k+1) == obj->front;
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
obj->a = NULL;
obj->front = 0;
obj->tail = 0;
obj->k = 0;
free(obj);
}
鏈表形式

環隊結構體(鏈表)
typedef int CQDataType;//環隊資料型別
typedef struct CQNode
{
CQDataType x;//環隊節點資料
struct CQNode* next;//環隊節點指標
}CQNode;
typedef struct {
CQNode* head;
CQNode* tail;
int k;
} MyCircularQueue;//慷訓隊就兩個裸指標
環隊初始化
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
CQNode* cur = (CQNode*)malloc(sizeof(CQNode));
cq->k = k;
cq->head = cq->tail = cur;
while(k--)
{
CQNode* newnode = (CQNode*)malloc(sizeof(CQNode));
CQNode* tail = cq->tail;//最后一個節點
tail->next = newnode;//最后一個節點指向新的節點
newnode->next = cq->head;//新的節點指向頭節點
cq->tail=newnode;
}
cq->head = cq->tail;
return cq;
}
判斷環隊為空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
return obj->head == obj->tail;
}
判斷環隊為滿
bool myCircularQueueIsFull(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
return obj->tail->next == obj->head;
}
環隊入資料并入成功回傳真
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
assert(obj->head && obj->tail);
if(!myCircularQueueIsFull(obj))
{
obj->tail->x = value;
obj->tail = obj->tail->next;
return true;
}
return false;
}
環隊刪資料并刪成功回傳真
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
if(!myCircularQueueIsEmpty(obj))
{
obj->head = obj->head->next;
return true;
}
return false;
}
環隊取隊頭資料(對慷訓傳-1)
int myCircularQueueFront(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
if(!myCircularQueueIsEmpty(obj))
return obj->head->x;
return -1;
}
環隊取隊尾資料(對慷訓傳-1)
int myCircularQueueRear(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
if(!myCircularQueueIsEmpty(obj))
{
CQNode*ret=obj->head;
while(ret->next!=obj->tail)
{
ret=ret->next;
}
return ret->x;
}
return -1;
}
環隊銷毀
void myCircularQueueFree(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
while(obj->head!=obj->tail)
{
CQNode*ret=obj->tail;
obj->tail=obj->tail->next;
free(ret);
}
free(obj->head);
free(obj);
}

環隊(鏈表實作)
typedef int CQDataType;//環隊資料型別
typedef struct CQNode
{
CQDataType x;//環隊節點資料
struct CQNode* next;//環隊節點指標
}CQNode;
typedef struct {
CQNode* head;
CQNode* tail;
int k;
} MyCircularQueue;//慷訓隊就兩個裸指標
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
CQNode* cur = (CQNode*)malloc(sizeof(CQNode));
cq->k = k;
cq->head = cq->tail = cur;
while(k--)
{
CQNode* newnode = (CQNode*)malloc(sizeof(CQNode));
CQNode* tail = cq->tail;//最后一個節點
tail->next = newnode;//最后一個節點指向新的節點
newnode->next = cq->head;//新的節點指向頭節點
cq->tail=newnode;
}
cq->head = cq->tail;
return cq;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
assert(obj->head && obj->tail);
if(!myCircularQueueIsFull(obj))
{
obj->tail->x = value;
obj->tail = obj->tail->next;
return true;
}
return false;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
if(!myCircularQueueIsEmpty(obj))
{
obj->head = obj->head->next;
return true;
}
return false;
}
int myCircularQueueFront(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
if(!myCircularQueueIsEmpty(obj))
return obj->head->x;
return -1;
}
/*int myCircularQueueRear(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
if(!myCircularQueueIsEmpty(obj))
{
CQNode* ret = obj->head;//這個ret 是用來找tail前一個的,不可用直接回傳tail,會改變原來環隊的鏈接關系
while(--obj->k)
{
obj->tail = obj->tail->next;
}
ret = obj->tail;
obj->tail = obj->tail->next;
return obj->tail->x;
}
return -1;
}*/
int myCircularQueueRear(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
if(!myCircularQueueIsEmpty(obj))
{
CQNode*ret=obj->head;
while(ret->next!=obj->tail)
{
ret=ret->next;
}
return ret->x;
}
return -1;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
return obj->head == obj->tail;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
return obj->tail->next == obj->head;
}
void myCircularQueueFree(MyCircularQueue* obj) {
assert(obj->head && obj->tail);
while(obj->head!=obj->tail)
{
CQNode*ret=obj->tail;
obj->tail=obj->tail->next;
free(ret);
}
free(obj->head);
free(obj);
}
實際上這題我報錯我不想找了太惡心了(家凌幫我找錯的非常感謝)

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/349615.html
標籤:其他
上一篇:【資料結構】二叉樹的定義以及性質
