【隊】用鏈表

特別要注意的是,新設定兩個指向鏈表結點的指針,rear和front,其中鏈表的結構體和指針的結構體定義如下

其中指針的結構體是無名結構體。有規定如果結構體中的成員,是一個指向結構體的指針,那麼該結構體一定要是本結構體。但是這個無名結構體並不符合這個規定(問了老師我還是不明白爲什麼,雖然運行沒問題,我把無名結構體又加了名字變成有名結構體還是運行沒問題。。。)

老師甩了這個鏈接給我:無名結構體的一個妙用

 

本代碼中存放數據用的是不帶頭結點的鏈表,好像頭結點對於這裏來說沒什麼用

//這個函數定義鏈表的頭是front(用來pop出的),尾是rear(用來push進的)

#include <stdio.h>
#include <stdlib.h>

enum return_val {EMPTY_OK, EMPTY_NO, ENTER_OK, ENTER_NO, DELETE_OK, DELETE_NO, GET_OK, GET_NO};

typedef struct queue_data
{
    int num;

    struct queue_data * next;
} QueueNode;

typedef struct
{
    QueueNode *front;
    QueueNode *rear;
} LinkQueue;

void InitQueue(LinkQueue *Q)
{
    Q->rear = Q->front = NULL;
}

int QueueEmpty(LinkQueue *Q)
{
    if(Q->front == NULL)
    {
        return EMPTY_OK;
    }
    return EMPTY_NO;
}

int GetFront(LinkQueue *Q,int *num)
{
    if(QueueEmpty(Q) == EMPTY_OK)
        return GET_NO;

    *num = Q->front->num;
    return GET_OK;
}

int EnQueue(LinkQueue *Q,int num)
{
    QueueNode *p;
    if(create_node(&p) == 0)
    {
        return ENTER_NO;
    }

    p->num = num;
    p->next = NULL;

    if(Q->front == NULL)
    {
        Q->front = p;
        Q->rear = p;
    }
    else
    {
        Q->rear->next = p;
        Q->rear = p;
    }
    return ENTER_OK;
}

int DeQueue(LinkQueue *Q,int *num)
{
    QueueNode *p;

    if(QueueEmpty(Q) == EMPTY_OK)
    {
        return DELETE_NO; 
    }

    p = Q->front;

    *num = p->num;
    Q->front = Q->front->next;

    if(Q->front == NULL)
    {
        Q->rear = NULL;
    }
    free(p);

    return DELETE_OK;

}

int is_malloc_ok(QueueNode *node)
{
    if(node == NULL)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

int create_node(QueueNode **node)
{
    int count = 10;

    do
    {
        *node = (QueueNode*)malloc(sizeof(QueueNode));
        count--;

        if(count == 0)
        {
            return 0;
        }
    }while(!is_malloc_ok(*node));

    return 1;
}

void ReleaseQueue(LinkQueue *Q)
{
    QueueNode *p;

    while(Q->front != Q->rear)
    {
        p = Q->front;
        Q->front = Q->front->next;
        free(p);
    }

    p = Q->front;
    Q->front = NULL;
    Q->rear = NULL;
    free(p);
}

int main()
{
    LinkQueue Q;

    int i;
    int num;

    InitQueue(&Q);

    for(i = 0; i < 5; i++)
    {
        if(EnQueue(&Q,i + 1) == ENTER_NO)
        {
            printf("enter no!\n");
        }
        else
        {
            printf("enter ok! num is %d\n",i + 1);
        }
    }

    for(i = 0; i < 3; i++)
    {
        if(GetFront(&Q,&num) == GET_NO)
        {
            printf("get no!\n");
        }
        else
        {
            printf("get ok! num is %d\n",num);
            DeQueue(&Q,&num);
        }
    }

    for(i = 0; i < 4; i++)
    {
        if(DeQueue(&Q,&num) == DELETE_NO)
        {
            printf("delete no!\n");
        }
        else
        {
            printf("delete ok! num is %d\n",num);
        }
    }

    ReleaseQueue(&Q);
    return 0;
}

小練:

要注意的問題:

  1. 用帶頭結點還是不帶頭結點的鏈表?
  2. 兩個struct結構體裏面的內容
  3. 新建Queue的操作,進隊出隊頭指針尾指針的指向改變(特別是出隊到隊空的時候隊尾指針指向要加上!!!)
  4. 老師的Queue創建時不是指針,好像還真用不到指針直接進入InitQueue,我還用了指針
  5. 出隊入隊的函數名怎麼取的
#include <stdio.h>
#include <stdlib.h>

struct queue_data
{
	int num;
	struct queue_data *next;
};

typedef struct queue_data QueueNode;

struct queue
{
	QueueNode *front;
	QueueNode *rear;
};

typedef struct queue Queue;

int CreateNode(QueueNode **node)
{
	*node = (QueueNode *)malloc(sizeof(QueueNode));
	if(*node == NULL)
		return 0;
	return 1;
}

int CreateQueue(Queue **q)
{
	*q = (Queue *)malloc(sizeof(Queue));
	if(*q == NULL)
		return 0;
	(*q)->front = NULL;
	(*q)->rear = NULL;
	return 1;
}

int IsEmpty(Queue *q)
{
	if(q->front == NULL)
		return 1;
	return 0;
}

int EnQueue(Queue *q, int num)
{
	QueueNode *node;

	if(!CreateNode(&node))
		return 0;

	node->num = num;

	if(IsEmpty(q))
	{
		q->front = node;
		q->rear = node;
	}
	else
	{
		q->rear->next = node;
		q->rear = node;
	}

	node->next = NULL;
	return 1;
}

int DeQueue(Queue *q, int *num)
{
	QueueNode *node;

	if(IsEmpty(q))
	{
		return 0;
	}

	node = q->front;
	*num = node->num;
	q->front = node->next;
	free(node);

	if(q->front == NULL)
	{
		q->rear = NULL;
	}
}

int GetTop(Queue *q,int *num)
{
	if(IsEmpty(q))
	{
		return 0;
	}

	*num = q->front->num;
	return 1;
}

void EmptyQueue(Queue *q)
{
	int num;

	while(DeQueue(q, &num));
}

void ReleaseQueue(Queue **q)
{
	EmptyQueue(*q);
	free(*q);
}


int main()
{
	Queue *q;
	int i = 0, num  = 1;
	int temp;

	CreateQueue(&q);

	while(i < 10 && EnQueue(q, num))
	{
		i++;
		num++;
		if(GetTop(q, &temp))
		{
			printf("%d\n",temp);
		}
	}

	printf("----------------\n");

	while(DeQueue(q, &num))
	{
		printf("%d\n",num);
	}

	ReleaseQueue(&q);
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章