打印
[经验分享]

数据结构之线性表

[复制链接]
90|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一.线性表之顺序表
顺序表的基本运算
设线性表 L=(a0,a1, ……,an-1),对 L的基本运算有:
(1)建立一个空表:list_create(L)
定义结构体指针L
申请内存malloc
判断是否为空
初始化L和last标志位
返回L
(2)置空表:list_clear(L)
判断L是否为空
初始化L和last起始标志位
(3)判断表是否为空:list_empty (L)。若表为空,返回值为1 , 否则返回 0
判断last标志位是否为起始标志位
4)求表长:length (L)
判断L是否为空
返回last+1
5)取表中某个元素:GetList(L , i ), 即ai。要求0≤i≤length(L)-1
6)定位运算:Locate(L,x)。确定元素x在表L中的位置(或序号)

                    i   当元素x=ai∈L,且ai是第一个与x相等时;
  Locate(L,x)=     -1    x不属于L时。


循环遍历[i-last]元素,找到相同的元素

7)插入:
Insert(L,x,i)。将元素x插入到表L中第i个元素ai之前,且表长+1。
插入前: (a0,a1,—,ai-1,ai,ai+1-------,an-1) 0≤i≤n,i=n时,x插入表尾
插入后: (a0,a1,—,ai-1, x, ai,ai+1-------,an-1)
判断是否满
判断位置是否合适
循环往后移动并赋值
插入新值
last++;

8)删除:
Delete(L,i)。删除表L中第i个元素ai,且表长减1, 要求0≤i≤n-1。
删除前: (a0,a1,—,ai-1,ai,ai+1-------,an-1)
删除后: (a0,a1,—,ai-1,ai+1-------,an)
判断是否为空
判断位置是否合适
循环往前移动覆盖
last–;

9)释放内存
free(L)
L置0

sqlist.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlist.h"

sqlink list_create() {
        //malloc
        sqlink L;

        L =(sqlink)malloc(sizeof(sqlist));
        if (L == NULL) {
                printf("list malloc failed\n");
                return L;
        }

        //initialize
        memset(L, 0, sizeof(sqlist));
        L->last = -1;

        //return
        return L;
}

/*
* @RET   0-success   -1-failed
* */
int list_clear(sqlink L) {
        if (L == NULL)
                return -1;

        memset(L, 0, sizeof(sqlist));
        L->last = -1;

        return 0;
}

int list_free(sqlink L){
        if (L == NULL)
                return -1;
        free(L);
        L = NULL;
        return 0;
}

/*
* list_empty: Is list empty?
* para L: list
* @ret  1--empty   0--not empty
* */
int list_empty(sqlink L) {
        if (L->last == -1)
                return 1;
        else
                return 0;
}

int list_length(sqlink L) {
        if (L == NULL)
                return -1;
        return (L->last+1);
}

/*
* @ret  -1--not exist   pos
* */
int list_locate(sqlink L, data_t value) {
        int i ;
        for (i = 0; i <= L->last; i++) {
                if (L->data == value)
                        return i;
        }

        return -1;
}

int list_insert(sqlink L, data_t value, int pos) {
        int i;

        //full
        if (L->last == N-1) {
                printf("list is full\n");
                return -1;
        }

        //check para    0<=pos<=Last+1   [0, last+1]
        if (pos < 0 || pos > L->last+1) {
                printf("Pos is invalid\n");
                return -1;
        }

        //move
        for (i = L->last; i >= pos; i--) {
                L->data[i+1] = L->data;
        }

        //update value last
        L->data[pos] = value;
        L->last++;

        return 0;
}

int list_show(sqlink L) {
        int i;

        if (L == NULL)
                return -1;
        if (L->last == -1)
                printf("list is empty\n");

        for (i = 0; i <= L->last; i++) {
                printf("%d ", L->data);
        }
        puts("");

        return 0;
}

int list_delete(sqlink L, int pos) {
        int i;

        if (L->last == -1) {
                printf("list is empty\n");
                return -1;
        }

        //pos [0, last]
        if (pos < 0 || pos > L->last) {
                printf("delete pos is invalid\n");
                return -1;
        }

        //move  [pos+1, last]
        for (i = pos+1; i <= L->last; i++) {
                L->data[i-1] = L->data;
        }

        //update
        L->last--;

        return 0;
}

int list_merge(sqlink L1, sqlink L2) {
        int i = 0;
        int ret;

        while (i <= L2->last){
                ret = list_locate(L1, L2->data);
                if (ret == -1) {
                        if (list_insert(L1, L2->data, L1->last+1) == -1)
                                return -1;
                }

                i++;
        }
        return 0;
}

int list_purge(sqlink L) {
        int i;
        int j;

        if (L->last == 0)
                return 0;

        i = 1;
        while (i <= L->last) {
                j = i-1;
                while (j >= 0) {
                        if (L->data == L->data[j]) {
                                list_delete(L, i);
                                break;
                        } else {
                                j--;
                        }
                }

                if ( j < 0) {
                        i++;
                }
        }

        return 0;
}




sqlist.h

typedef int data_t;
#define N 128

typedef struct {
        data_t data[N];
        int last;
}sqlist, *sqlink;

sqlink list_create();
int list_clear(sqlink L);
int list_free(sqlink L);
int list_empty(sqlink L);
int list_length(sqlink L);
int list_locate(sqlink L, data_t value);
int list_insert(sqlink L, data_t value, int pos);
int list_delete(sqlink L, int pos);
int list_merge(sqlink L1, sqlink L2);
int list_purge(sqlink L);
int list_show(sqlink L);




test.c

#include <stdio.h>
#include "sqlist.h"

void test_insert();
void test_delete();
void test_merge();
void test_purge();

int main(int argc, const char *argv[])
{
        //test_insert();
        //test_delete();
        //test_merge();
        test_purge();

        return 0;
}

void test_insert() {
        sqlink L;
       
        L = list_create();
        if (L == NULL)
                return;

        list_insert(L, 10, 0);
        list_insert(L, 20, 0);
        list_insert(L, 30, 0);
        list_insert(L, 40, 0);
        list_insert(L, 50, 0);
        list_insert(L, 60, 0);

        list_show(L);
        //list_insert(L, 100, list_length(L));
        list_insert(L, 100, -1000);
        list_show(L);
        list_free(L);
}

void test_delete() {
        sqlink L;
       
        L = list_create();
        if (L == NULL)
                return;

        list_insert(L, 10, 0);
        list_insert(L, 20, 0);
        list_insert(L, 30, 0);
        list_insert(L, 40, 0);
        list_insert(L, 50, 0);
        list_insert(L, 60, 0);

        list_show(L);
        list_delete(L, 9);
        list_show(L);

        list_free(L);
}

void test_merge() {
        sqlink L1, L2;

        L1 = list_create();
        if (L1 == NULL)
                return;

        L2 = list_create();
        if (L2 == NULL)
                return;

        list_insert(L1, 10, 0);
        list_insert(L1, 20, 0);
        list_insert(L1, 30, 0);
        list_insert(L1, 40, 0);

        list_insert(L2, 50, 0);
        list_insert(L2, 20, 0);
        list_insert(L2, 90, 0);
        list_insert(L2, 40, 0);

        list_show(L1);
        list_show(L2);
        printf("********************\n");
        list_merge(L1, L2);
        list_show(L1);
        list_show(L2);
}

void test_purge() {
        sqlink L;
       
        L = list_create();
        if (L == NULL)
                return;

        list_insert(L, 10, 0);
        list_insert(L, 10, 0);
        list_insert(L, 10, 0);
        list_insert(L, 10, 0);
        list_insert(L, 10, 0);
        list_insert(L, 10, 0);

        list_show(L);
        list_purge(L);
        list_show(L);

        list_free(L);
}




线性表的优劣
线性表的顺序存储结构有存储密度高及能够随机存取等优点,但存在以下不足:
(1)要求系统提供一片较大的连续存储空间。
(2)插入、删除等运算耗时,且存在元素在存储器中成片移动的现象;

二.线性表之单链表
将线性表L=(a0,a1,……,an-1)中各元素分布在存储器的不同存储块,称为结点,通过地址或指针建立元素之间的联系 。结点的data域存放数据元素ai,而next域是一个指针,指向ai的直接后继ai+1所在的结点。

获取ai,写作:p->data;
而取ai+1,写作:p->next->data
若指针p的值为NULL,则它不指向任何结点, 此时取p->data或p->next是错误的。

结点类型描述:
      typedef   struct  node
      {   data_t   data;   //结点的数据域//
           struct node *next;  //结点的后继指针域//
       }listnode, *linklist;



1)建立单链表
依次读入表L=(a0,…,an-1)中每一元素ai(假设为整型),若ai≠结束符(-1),则为ai创建一结点,然后插入表尾,最后返回链表的头结点指针H。
申请内存,判断L头节点是否为空
赋初值,结构指针赋值0,NULL;
返回L头节点

2)链表查找
按序号查找:实现GetLinklist(h, i)运算。
算法思路:从链表的a0起,判断是否为第i结点,若是则返回该结点的指针,否则查找下一结点,依次类推。
判断位置是否合理
pos=-1,返回H
申请p,p=p->next,[-1,pos]循环
返回p

按值查找(定位) : 即实现Locate(h, x)。
算法思路:从链表结点a0起,依次判断某结点是否等于x,若是,则返回该结点的地址,若不是,则查找下一结点a1,依次类推。若表中不存在x,则返回NULL。

3)链表的插入
实现InsertLinklist(h, x, i,)。将x插入表中结点ai之前的情况。
算法思路:调用算法GetLinklist(h, i-1),获取结点ai-1的指针p(ai 之前驱),然后申请一个q结点,存入x,并将其插入p指向的结点之后。



尾部插入
申请新节点p,判断是否为空
赋初值
申请q,H开始循环赋值q=q->next,让q指向最后一个元素值
q->next=p;

4)链表的删除
实现DeleteLinklist(h, i), 算法对应的链表结构如图所示。
算法思路:同插入法,先调用函数GetLinklist(h, i-1),找到结点ai的前驱,然后将结点ai删除之。
申请q,q=p->next;
p->next=q->next;
释放内存

5)链表的展示
申请p,p=H
p->next不为空,循环打印p->next->data;p=p->next;

6)链表的释放
H不为空,则循环free§;H=H->next;



linklist.c

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

linklist list_create() {
        linklist H;

        H = (linklist)malloc(sizeof(listnode));
        if (H == NULL) {
                printf("malloc failed\n");
                return H;
        }
       
        H->data = 0;
        H->next = NULL;

        return H;
}

int list_tail_insert(linklist H, data_t value) {
        linklist p;
        linklist q;

        if (H == NULL) {
                printf("H is NULL\n");
                return -1;
        }

        //1 new node p
        if ((p = (linklist)malloc(sizeof(listnode))) == NULL) {
                printf("malloc failed\n");
                return -1;
        }
        p->data = value;
        p->next = NULL;
       
        //2 locate locate locate locate locate locate locate locate locate tail node
        q = H;
        while (q->next != NULL) {
                q = q->next;
        }

        //3 insert
        q->next = p;

        return 0;
}

linklist list_get(linklist H, int pos) {
        linklist p;
        int i;

        if (H == NULL) {
                printf("H is NULL\n");
                return NULL;
        }

        if (pos == -1) {
                return H;
        }

        if (pos < -1) {
                printf("pos is invalid\n");
                return NULL;
        }

        p = H;
        i = -1;
        while (i < pos) {
                p = p->next;
                if (p == NULL) {
                        printf("pos is invalid\n");
                        return NULL;
                }
                i++;
        }

        return p;
}

int list_insert(linklist H, data_t value, int pos) {
        linklist p;
        linklist q;

        if (H == NULL) {
                printf("H is NULL\n");
                return -1;
        }

        //1 locate node p (pos-1)
        p = list_get(H, pos-1);
        if (p == NULL) {
                return -1;
        }

        //2 new node q
        if ((q = (linklist)malloc(sizeof(listnode))) == NULL) {
                printf("malloc failed\n");
                return -1;
        }
        q->data = value;
        q->next = NULL;

        //3 insert
        q->next = p->next;
        p->next = q;

        return 0;
}

int list_delete(linklist H, int pos) {
        linklist p;
        linklist q;

        //1
        if (H == NULL) {
                printf("H is NULL\n");
                return -1;
        }

        //2 locate prior
        p = list_get(H, pos-1);
        if (p == NULL)
                return -1;
        if (p->next == NULL) {
                printf("delete pos is invalid\n");
                return -1;
        }

        //3 update list
        q = p->next;
        p->next = q->next;//p->next = p->next->next;

        //4 free
        printf("free:%d\n", q->data);
        free(q);
        q = NULL;

        return 0;
}

int list_show(linklist H) {
        linklist p;

        if (H == NULL) {
                printf("H is NULL\n");
                return -1;
        }

        p = H;

        while (p->next != NULL) {
                printf("%d ", p->next->data);
                p = p->next;
        }
        puts("");

        return 0;
}

linklist list_free(linklist H) {
        linklist p;

        if (H == NULL)
                return NULL;

        p = H;

        printf("free:");
        while (H != NULL) {
                p = H;
                printf("%d ", p->data);
                free(p);
                H = H->next;
        }
        puts("");

        return NULL;
}



linklist.h

typedef int data_t;

typedef struct node {
        data_t data;
        struct node * next;
}listnode, * linklist;

linklist list_create();
int list_tail_insert(linklist H, data_t value);//head
linklist list_get(linklist H, int pos);
int list_insert(linklist H, data_t value, int pos);
int list_delete(linklist H, int pos);
int list_show(linklist H);
linklist list_free(linklist H);


test.c

#include <stdio.h>
#include "linklist.h"

void test_get();
void test_insert();

int main(int argc, const char *argv[])
{
        linklist H;
        int value;
       
        H = list_create();
        if (H == NULL)
                return -1;

        printf("input:");
        while (1) {
                scanf("%d", &value);
                if (value == -1)
                        break;
                list_tail_insert(H, value);
                printf("input:");
        }
       
        list_show(H);
        printf("H=%p\n", H);
        H = list_free(H);
        printf("H=%p\n", H);
        list_delete(H, -4);//1 3 5 7
        list_show(H);

        list_free(H);

        return 0;
}

void test_get() {
        linklist H;
        int value;
        linklist p;
       
        H = list_create();
        if (H == NULL)
                return;

        printf("input:");
        while (1) {
                scanf("%d", &value);
                if (value == -1)
                        break;
                list_tail_insert(H, value);
                printf("input:");
        }
       
        list_show(H);

        p = list_get(H, 4);//1 3 5 7
        if (p != NULL)
                printf("value=%d\n", p->data);
}

void test_insert() {
        linklist H;
        int value;
       
        H = list_create();
        if (H == NULL)
                return;

        printf("input:");
        while (1) {
                scanf("%d", &value);
                if (value == -1)
                        break;
                list_tail_insert(H, value);
                printf("input:");
        }
       
        list_show(H);
        list_insert(H, 100, 0);//1 3 5 7
        list_show(H);
}



5)将单链表H倒置
算法思路:依次取原链表中各结点,将其作为新链表首结点插入H结点之后

6)求链表中相邻两结点data值之和为最大的第一结点的指针。
算法思路:设p,q 分别为链表中相邻两结点指针,求p->data+q->data为最大的那一组值,返回其相应的指针p即可

7)设两单链表A、B按data值(设为整型)递增有序,将表A和B合并成一表A,且表A也按data值递增有序。
算法思路:设指针p、q分别指向表A和B中的结点,若p->data ≤q->data则p结点进入结果表,否则q结点进入结果表。

三.线性表的栈
栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈)
允许进行操作的一端称为“栈顶”,另一固定端称为“栈底”,当栈中没有元素时称为“空栈”。特点 :后进先出(LIFO)。

(1)顺序栈

它是顺序表的一种,具有顺序表同样的存储结构,由数组定义,配合用数组下标表示的栈顶指针top(相对指针)完成各种操作。

typedef int data_t ; /定义栈中数据元素的数据类型/
typedef struct
{
data_t *data ; /用指针指向栈的存储空间/
int maxlen; /当前栈的最大元素个数/
int top ; /指示栈顶位置(数组下标)的变量/
} sqstack; /顺序栈类型定义/
1)顺序栈的创建
先申请sqstack内存,再申请data[len]的内存
判断是否申请成功
变量初始化
2)顺序栈进栈
判断是否为满s->top==maxlen-1;
s->top++;
s->data[s->top];
3)栈是否为空
s->top是否为-1;
4)出栈
判断是否为空
s->top–;
s->data[s->top+1];
5)

sqstack.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqstack.h"

sqstack * stack_create(int len) {
        sqstack * s;

        if ((s =(sqstack *)malloc(sizeof(sqstack))) == NULL) {
                printf("malloc sqstack failed\n");
                return NULL;
        }

        if ((s->data = (data_t *)malloc(len * sizeof(data_t)))==NULL) {
                printf("malloc data failed\n");
                free(s);
                return NULL;
        }

        memset(s->data, 0, len*sizeof(data_t));
        s->maxlen = len;
        s->top = -1;

        return s;
}

int stack_push(sqstack * s, data_t value) {
        if (s == NULL) {
                printf("s is NULL\n");
                return -1;
        }

        if (s->top == s->maxlen-1) {
                printf("stack is full\n");
                return -1;
        }

        s->top++;
        s->data[s->top] = value;

        return 0;
}

/*
*@ret 1-empty
* */
int stack_empty(sqstack *s) {
        if (s == NULL) {
                printf("s is NULL\n");
                return -1;
        }
        return (s->top == -1 ? 1 : 0);
}

/*
* @ret 1-full
* */
int stack_full(sqstack *s) {
        if (s == NULL) {
                printf("s is NULL\n");
                return -1;
        }
        return  (s->top == s->maxlen-1 ? 1 : 0);
}

data_t stack_pop(sqstack *s) {
        s->top--;
        return (s->data[s->top+1]);
}

data_t stack_top(sqstack *s) {
        return (s->data[s->top]);
}

int stack_clear(sqstack *s) {
        if (s == NULL) {
                printf("s is NULL\n");
                return -1;
        }
       
        s->top = -1;
        return 0;
}

int stack_free(sqstack *s) {
        if (s == NULL) {
                printf("s is NULL\n");
                return -1;
        }
       
        if (s->data != NULL)
                free(s->data);
        free(s);

        return 0;
}



sqstack.h

typedef int data_t;

typedef struct {
        data_t *data;
        int maxlen;
        int top;
}sqstack;

sqstack * stack_create(int len);
int stack_push(sqstack * s, data_t value);
int stack_empty(sqstack *s);
int stack_full(sqstack *s);
data_t stack_pop(sqstack *s);
data_t stack_top(sqstack *s);
int stack_clear(sqstack *s);
int stack_free(sqstack *s);





test.c

#include <stdio.h>
#include "sqstack.h"

int main(int argc, const char *argv[])
{
        sqstack *s;

        s = stack_create(100);
        if (s == NULL)
                return -1;

        stack_push(s, 10);
        stack_push(s, 20);
        stack_push(s, 30);
        stack_push(s, 40);

        while (!stack_empty(s)) {
                printf("pop: %d \n", stack_pop(s) );
        }
       
        stack_free(s);

        return 0;
}



(2)链式栈
插入操作和删除操作均在链表头部进行,链表尾部就是栈底,栈顶指针就是头指针。
typedef int data_t ; /定义栈中数据元素数据类型/
typedef struct node_t {
data_t data ; /数据域/
struct node_t *next ; /链接指针域/
} linkstack_t ; /链栈类型定义/

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

linkstack stack_create() {
        linkstack s;

        s = (linkstack)malloc(sizeof(listnode));
        if (s == NULL) {
                printf("malloc failed\n");
                return NULL;
        }
        s->data = 0;
        s->next = NULL;

        return s;
}

int stack_push(linkstack s, data_t value) {
        linkstack p;

        if (s == NULL) {
                printf("s is NULL\n");
                return -1;
        }

        p = (linkstack)malloc(sizeof(listnode));
        if (p == NULL) {
                printf("malloc failed\n");
                return -1;
        }
        p->data = value;
        //p->next = NULL;
        p->next = s->next;
        s->next = p;

        return 0;
}

data_t stack_pop(linkstack s) {
        linkstack p;
        data_t t;

        p = s->next;
        s->next = p->next;

        t = p->data;

        free(p);
        p =NULL;

        return t;
}

int stack_empty(linkstack s) {
        if (s == NULL) {
                printf("s is NULL\n");
                return -1;
        }

        return (s->next == NULL ? 1 : 0);
}

data_t stack_top(linkstack s) {
        return (s->next->data);
}

linkstack stack_free(linkstack s) {
        linkstack p;

        if (s == NULL) {
                printf("s is NULL\n");
                return NULL;
        }

        while (s != NULL) {
                p = s;
                s = s->next;
                printf("free:%d\n", p->data);
                free(p);
        }

        return NULL;
}



typedef int data_t;

typedef struct node {
        data_t data;
        struct node *next;
}listnode, *linkstack;

linkstack stack_create();
int stack_push(linkstack s, data_t value);
data_t stack_pop(linkstack s);
int stack_empty(linkstack s);
data_t stack_top(linkstack s);
linkstack stack_free(linkstack s);


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

int main(int argc, const char *argv[])
{
        linkstack s;

        s = stack_create();
        if (s == NULL)
                return -1;

        stack_push(s, 10);
        stack_push(s, 20);
        stack_push(s, 30);
        stack_push(s, 40);

#if 0
        while (!stack_empty(s)) {
                printf("pop:%d\n", stack_pop(s));
        }
#endif

        s = stack_free(s);
       
        return 0;
}



四. 线性表之队列
(1)顺序队列
队列是限制在两端进行插入操作和删除操作的线性表
允许进行存入操作的一端称为“队尾”
允许进行删除操作的一端称为“队头”
当线性表中没有元素时,称为“空队”
特点 :先进先出(FIFO)

规定:front指向队头元素的位置; rear指向队尾元素的下一个位置。
在队列操作过程中,为了提高效率,以调整指针代替队列元素的移动,并将数组作为循环队列的操作空间。
为区别空队和满队,满队元素个数比数组元素个数少一个

1)创建队列 :CreateQueue ()
申请内存,赋值
前后标准位初始化

2)清空队列 :ClearQueue (Q)
s->rears->front=0;
3)判断队列空 :EmptyQueue(Q)
s->rears->front;
4)判断队列满 :FullQueue(Q)
(s->rear+1)%N==s->front
5)入队 :EnQueue (Q , x)
判断是否为NULL,是否满了
赋值给对尾s->data[s->rear]=x
s->rear=(s->rear+1)%N;
6)出队 :DeQueue(Q)
ret = sq->data[sq->front];
sq->front = (sq->front + 1) % N;

sequeue.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sequeue.h"

sequeue * queue_create() {
        sequeue *sq;

        if ((sq = (sequeue *)malloc(sizeof(sequeue))) == NULL) {
                printf("malloc failed\n");
                return NULL;
        }

        memset(sq->data, 0, sizeof(sq->data));
        sq->front = sq->rear = 0;
        return sq;
}

int enqueue(sequeue *sq, datatype x) {
        if (sq == NULL) {
                printf("sq is NULL\n");
                return -1;
        }

        if ((sq->rear + 1) % N == sq->front) {
                printf("sequeue is full\n");
                return -1;
        }

        sq->data[sq->rear] = x;
        sq->rear = (sq->rear + 1) % N;

        return  0;
}

datatype dequeue(sequeue *sq) {
        datatype ret;

        ret = sq->data[sq->front];

        sq->front = (sq->front + 1) % N;

        return ret;
}

int queue_empty(sequeue *sq) {
        if (sq == NULL) {
                printf("sq is NULL\n");
                return -1;
        }

        return (sq->front == sq->rear ? 1 : 0);
}

int queue_full(sequeue *sq) {
        if (sq == NULL) {
                printf("sq is NULL\n");
                return -1;
        }

        if ((sq->rear + 1) % N == sq->front) {
                return 1;
        }
        else {
                return 0;
        }
}

int queue_clear(sequeue *sq) {
        if (sq == NULL) {
                printf("sq is NULL\n");
                return -1;
        }

        sq->front = sq->rear = 0;

        return 0;
}

sequeue * queue_free(sequeue *sq) {
        if (sq == NULL) {
                printf("sq is NULL\n");
                return NULL;
        }

        free(sq);
        sq = NULL;

        return NULL;
}



sequeue.h

typedef int datatype;
#define N 128

typedef struct {
        datatype data[N];
        int front;
        int rear;
}sequeue;

sequeue * queue_create();
int enqueue(sequeue *sq, datatype x);
datatype dequeue(sequeue *sq);
int queue_empty(sequeue *sq);
int queue_full(sequeue *sq);
int queue_clear(sequeue *sq);
sequeue * queue_free(sequeue *sq);



test.c

#include <stdio.h>
#include "sequeue.h"

int main(int argc, const char *argv[])
{
        sequeue *sq;

        if ((sq = queue_create()) == NULL) {
                return -1;
        }
       
        enqueue(sq, 10);
        enqueue(sq, 100);
        enqueue(sq, 1000);

        while (!queue_empty(sq)) {
                printf("dequeue:%d\n", dequeue(sq));
        }

        queue_free(sq);

        return 0;
}



(2)链式队列
1)创建队列
为队列申请内存
为头尾节点申请内存
赋初值

2)入队
申请新节点为入队元素
队尾放入

3)出队
申请新节点指向队头
队头指向下一个节点

4)判断是否为空
队头与队尾指向相同
5)清空
队头指向空
6)释放
队头为空
linkqueue.c

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

linkqueue * queue_create() {
        linkqueue *lq;

        if ((lq = (linkqueue *)malloc(sizeof(linkqueue))) == NULL) {
                printf("malloc linkqueue failed\n");
                return NULL;
        }

        lq->front = lq->rear = (linklist)malloc(sizeof(listnode));
        if (lq->front == NULL) {
                printf("malloc node failed\n");
                return NULL;
        }
        lq->front->data = 0;
        lq->front->next = NULL;

        return lq;
}

int enqueue(linkqueue *lq, datatype x) {
        linklist p;

        if (lq == NULL) {
                printf("lq is NULL\n");
                return -1;
        }

        if ((p = (linklist)malloc(sizeof(listnode))) == NULL) {
                printf("malloc node failed\n");
                return -1;
        }
        p->data = x;
        p->next = NULL;

        lq->rear->next = p;
        lq->rear = p;

        return 0;
}

datatype dequeue(linkqueue *lq) {
        linklist p;

        if (lq == NULL) {
                printf("lq is NULL\n");
                return -1;
        }

        p = lq->front;
        lq->front = p->next;
        free(p);
        p = NULL;

        return (lq->front->data);
}

int queue_empty(linkqueue *lq) {
        if (lq == NULL) {
                printf("lq is NULL\n");
                return -1;
        }

        return (lq->front == lq->rear ? 1 : 0);
}

int queue_clear(linkqueue *lq) {
        linklist p;

        if (lq == NULL) {
                printf("lq is NULL\n");
                return -1;
        }

        while (lq->front->next) {
                p = lq->front;
                lq->front = p->next;
                printf("clear free:%d\n", p->data);
                free(p);
                p = NULL;
        }
        return 0;
}

linkqueue * queue_free(linkqueue *lq) {
        linklist p;

        if (lq == NULL) {
                printf("lq is NULL\n");
                return NULL;
        }

        while (lq->front) {
                p = lq->front;
                lq->front = p->next;
                printf("free:%d\n", p->data);
                free(p);
        }

        free(lq);
        lq = NULL;

        return NULL;
}





linkqueue.h

typedef int datatype;

typedef struct node {
        datatype data;
        struct node *next;
}listnode , *linklist;

typedef struct {
        linklist front;
        linklist rear;
}linkqueue;

linkqueue * queue_create();
int enqueue(linkqueue *lq, datatype x);
datatype dequeue(linkqueue *lq);
int queue_empty(linkqueue *lq);
int queue_clear(linkqueue *lq);
linkqueue * queue_free(linkqueue *lq);



test.c

#include <stdio.h>
#include "linkqueue.h"

int main(int argc, const char *argv[])
{
        linkqueue *lq;

        lq = queue_create();
        if (lq == NULL)
                return -1;

        enqueue(lq, 10);
        enqueue(lq, 20);
        enqueue(lq, 30);
        enqueue(lq, 40);

        //while (!queue_empty(lq)) {
                //printf("dequeue:%d\n", dequeue(lq));
        //}
        queue_clear(lq);

        lq = queue_free(lq);
        enqueue(lq, 50);

        return 0;
}




————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_55389449/article/details/140106684

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

4256

帖子

2

粉丝