数据结构 线性链表 模拟队列

1、头文件seqlist.h

复制代码
 1 #ifndef __SEQLIST_H__
 2 #define __SEQLIST_H__
 3 #include <stdio.h>
 4 
 5 typedef void SeqList;     // 定义一个链表类型
 6 typedef void SeqListNode; // 定义链表结点
 7 
 8 SeqList* Creat_SeqList(int capcity);   // 根据容量创建链表
 9 
10 void Destory_SeqList(SeqList* list);   // 销毁链表
11 
12 void Clear_SeqList(SeqList* list);     // 清空链表
13 
14 int GetLen_SeqList(SeqList* list);     // 获取链表长度
15 
16 int GetCap_SeqList(SeqList* list);     // 获取链表容量
17 
18 int InsertNode_SeqList(SeqList* list,SeqListNode* node,int pos);// 在链表pos位置插入一个节点node
19 
20 SeqListNode* GetNode_SeqList(SeqList* list,int pos);  // 根据pos获取链表节点
21 
22 SeqListNode* Delete_SeqList(SeqList* list,int pos);   // 根据pos删除链表节点
23 
24 #endif
复制代码

2、seqlist.c实现接口

复制代码
  1 #include "seqlist.h"
  2 #include <stdlib.h>
  3 #include <string.h>
  4 
  5 
  6 // 定义节点 
  7 // 在结构体中套一级指针
  8 typedef struct _Tag_TSeqList{
  9     int length;
 10     int capcity;
 11     unsigned int* p;   // 定义的是一个链表类型结构
 12 }TSeqList;
 13 
 14 
 15 // 根据容量创建链表
 16 SeqList* Creat_SeqList(int capcity)
 17 {
 18     TSeqList* tmp = NULL;
 19     tmp = (TSeqList*)malloc(sizeof(TSeqList));
 20     if(capcity < 0){
 21         printf("input capcity err\n");
 22         return NULL;
 23     }
 24     if(tmp == NULL){
 25         printf("func malloc failed\n");
 26         return NULL;
 27     }
 28     memset(tmp,0,sizeof(TSeqList));
 29     // 根据容量capcity分配节点大小
 30     tmp->p = (unsigned int*)malloc(sizeof(unsigned int*) * capcity);
 31     if(tmp->p == NULL){
 32         printf("func malloc tmp->p failed \n");
 33         return NULL;
 34     }
 35     tmp->capcity = capcity;
 36     tmp->length = 0;
 37     return tmp;   // 返回的是个空链表  // 需要注意的是malloc内存后,并没有释放内存,因此数据还是存在内存中;
 38 }
 39 
 40 // 销毁链表
 41 void Destory_SeqList(SeqList* list)
 42 {
 43     TSeqList* tlist = NULL;
 44     if(list == NULL){
 45         printf("func return list is NULL\n");
 46         return;
 47     }
 48     tlist = (TSeqList*)list;
 49     // 销毁链表,创建的时候malloc 两次tmp = (TSeqList*)malloc(sizeof(TSeqList));、
 50     // tmp->p = (unsigned int*)malloc(sizeof(unsigned int*) * capcity);
 51     // 因此需要释放两次
 52     if(tlist->p != NULL){
 53         free(tlist->p);  // 释放链表节点空间 需要先释放内部数据,在释放整体
 54     }
 55     free(tlist);      // 释放链表空间
 56     return ;
 57 } 
 58 // 清空链表 链表回到初始化状态
 59 void Clear_SeqList(SeqList* list)
 60 {
 61     TSeqList* tlist = NULL;
 62     if(list == NULL){
 63         printf("list is NULL clear failed\n");
 64         return ;
 65     }
 66     tlist = (TSeqList*)list;  // 将list清空空
 67     tlist->length = 0;        // list长度为0
 68 } 
 69 // 获取链表长度
 70 int GetLen_SeqList(SeqList* list)
 71 {
 72     TSeqList* tlist = NULL;
 73     if(list == NULL){
 74         printf("list is NULL return\n");
 75         return -1;
 76     }
 77     tlist = (TSeqList*)list;
 78     return tlist->length;   /// 返回链表长度
 79 }
 80 // 获取链表容量
 81 int GetCap_SeqList(SeqList* list)
 82 {
 83     TSeqList* tlist = NULL;
 84     if(list == NULL){
 85         printf("list is NULL return\n");
 86         return -1;
 87     }
 88     tlist = (TSeqList*)list;
 89     return tlist->capcity; // 返回链表容量
 90 }   
 91 // 在链表pos位置插入一个节点node
 92 int InsertNode_SeqList(SeqList* list,SeqListNode* node,int pos)
 93 {
 94     int i = 0; /// 定义节点索引
 95     TSeqList* tlist = NULL;
 96     if(list == NULL||node == NULL|| pos < 0){
 97         printf("input parameter err\n");
 98         return -1;
 99     }
100     tlist = (TSeqList*)list;
101     if(tlist->capcity <= tlist->length){
102         printf("list is full insert failed\n");
103         return -2;
104     }
105     // 插入位置超前了  冗余处理
106     if(tlist->length <= pos){
107         pos = tlist->length;
108     }
109     // 元素移动
110     for(i = tlist->length;i<pos;i++){
111         tlist->p[i] = tlist->p[i-1];
112     }
113     // 插入元素
114     tlist->p[i] = (unsigned int)node;
115     tlist->length++;  // 链表长度递增
116     return 0;
117 }
118 // 根据pos获取链表节点
119 SeqListNode* GetNode_SeqList(SeqList* list,int pos)
120 {
121     TSeqList* tlist = NULL;
122     SeqListNode* node = NULL;
123     if(list == NULL){
124         printf("list is NULL\n");
125         return NULL;
126     }
127     tlist = (TSeqList*)list;
128     if(tlist->length < pos|| pos < 0){
129         printf("input pos err\n");
130         return NULL;
131     }
132     node = (SeqListNode*)tlist->p[pos];
133     return node;
134 } 
135 // 根据pos删除链表节点
136 SeqListNode* Delete_SeqList(SeqList* list,int pos)
137 {
138     TSeqList* tlist = NULL;
139     SeqListNode* tmp = NULL;
140     int i = 0;
141     if(list == NULL){
142         printf("list is NULL\n");
143         return NULL;
144     }
145     tlist = (TSeqList*)list;
146     if(tlist->length < pos || pos < 0){
147         printf("input pos err\n");
148         return NULL;
149     }
150     tmp = (SeqListNode*)tlist->p[pos];
151     for(i=pos+1;i<tlist->length;i++){
152         tlist->p[i-1] = tlist->p[i];
153     }
154     tlist->length++;
155     return tmp;
156 }
复制代码

3、main.c线性表测试

复制代码
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include "seqlist.h"
 4 
 5 // 定义自己的数据体
 6 typedef struct _Teacher{
 7     int age;
 8     char *name;
 9 }Teacher;
10 
11 int main()
12 {
13     SeqList* list = NULL;
14     Teacher t1,t2,t3,t4;
15     int ret = 0,i = 0;
16 
17     t1.age = 21; t1.name = "LiMing";
18     t2.age = 23; t2.name = "WangWu";
19     t3.age = 26; t3.name = "LiuHua";
20     t4.age = 27; t4.name = "YangQing";
21 
22     // 创建一个链表
23     list = Creat_SeqList(10);
24     if(list == NULL){
25         printf("Creat list failed \n");
26         return -1;
27     }
28     ret = InsertNode_SeqList(list,(SeqListNode*)&t1,0);
29     ret = InsertNode_SeqList(list,(SeqListNode*)&t2,0);
30     ret = InsertNode_SeqList(list,(SeqListNode*)&t3,0);
31     ret = InsertNode_SeqList(list,(SeqListNode*)&t4,0);
32    
33     // 遍历链表
34     for(i = 0;i < GetLen_SeqList(list);i++){
35         Teacher* tmp = (Teacher*)GetNode_SeqList(list,i);
36         if(tmp == NULL)
37             return -2;
38         printf("name:%s...age:%d\n",tmp->name,tmp->age);
39     }
40 
41    return 0;
42 }
复制代码

4、在测试的时候,发现VS2012可以运行。但是使用gcc编译的时候,代码的强制类型转换,给出警告了,并且执行的时候出错;

5、多文件编译

gcc  seqlist.c main.c -o output.out

6、链表的链式存储

  结构体+结构体指针+数据域封装

复制代码
#include <stdio.h>
#include <stdlib.h>

// 自定义节点类型
typedef struct node{
    int data;          // 数据域
    struct node* next; // 指针域 存储节点的地址
}Node;

void main()
{
    int tmp;
    Node * head,*p,*last;
    head = p = last =NULL;
    printf("请输入数据,输入0结束\n");
    scanf("%d",&tmp);
    while(tmp !=0 )
    {
        p = (Node*)malloc(sizeof(Node));   // 新节点分配内存
        p->data = tmp;     // 保存数据
        if(head == NULL){  // 第一个节点
            head = p;       // 保存第一个节点的地址
        }else{                    // 不是第一个节点
            last->next = p;        // 上一个节点的next保存下一个节点的地址
        }
        last = p;     // last指针变量始终保存最后有个节点的地址,last向后移动
        printf("请输入数据,输入0结束\n");
        scanf("%d",&tmp);
    }
    last->next = NULL;   // 新节点增加完成后,最后一个节点的next指向NULL

    p = head;  // 从头开始遍历
    while(p != NULL)
    {
        printf("输入的数据为:%d\n",p->data);
        p = p->next;   // 指针变量向后移动
    }
    getchar();
    getchar();   // 用于程序暂停
}
复制代码

 

7、使用链表模拟队列

  队列模型:队列中的数据,首先进入的首先出去;FIFO

  定义数据结构:

复制代码
// 队列中数据节点的数据结构
typedef int Item;
typedef struct node{
    Item item;
    struct node * pNext;
}Node;

// 保存队列中队列首尾的位置
typedef struct queue{
    Node * front;   // 队列的首指针
    Node * rear;    // 队列尾指针
    int itemNum;   // 队列中项目个数
}Queue;
复制代码

  定义队列操作接口:

复制代码
#define MAXQUEUE 10  // 队列中最大数据节点数

/* 初始化一个空队列 */
void InitalizeQueue(Queue * qe);

/* 判断队列是否满了,满了返回True,否则false */
unsigned int QueueIsFull( Queue *qe);

/* 检查队列是否为空, 为空返回True否则返回false */
unsigned int QueueIsEmpty(const Queue* qe);

/* 确定队列中项目的个数, 返回队列中项目个数 */
unsigned int GetQueueItemCount(const Queue* qe);

/* 向队列尾部添加项目,添加成功返回True,否则返回false */
unsigned int AddItemEndQueue(Item item, Queue* qe);

/* 从队列首端清除一个Item,成功返回True,否则返回false */
/* 队列中第一个Item复制到item中,然后删除队列中的item */
unsigned int DeleteFirstItemQueue(Item* item, Queue* qe);

/* 清空队列 */
void EmptyQueue(Queue * qe);
复制代码

  队列接口实现:

复制代码
/* 初始化一个空队列 */
void InitalizeQueue(Queue* qe)
{
    qe->front = qe->rear = NULL;
    qe->itemNum =0;
}
/* 判断队列是否满了,满了返回1,否则0 */
unsigned int QueueIsFull(Queue *qe)
{
    if(qe->itemNum < MAXQUEUE)
        return 0;
    else
        return 1;
}

/* 检查队列是否为空, 为空返回1,否则返回0 */
unsigned int QueueIsEmpty(const Queue* qe)
{
    if(qe->itemNum == 0)
        return 1;
    else
        return 0;
}

/* 确定队列中项目的个数, 返回队列中项目个数 */
unsigned int GetQueueItemCount(const Queue* qe)
{
    return qe->itemNum;
}

/* 向队列尾部添加节点,添加成功返回0,否则返回1 */
unsigned int AddItemEndQueue(Item item, Queue* qe)
{
    Node* pNode;
    if(QueueIsFull(qe))
        return 1;
    pNode = (Node*)malloc(sizeof(Node));
    if(pNode == NULL){
        printf("malloc node memory failed\n");
        return 2;
    }
    pNode->item = item;
    pNode->pNext = NULL;

    if(QueueIsEmpty(qe)){
        qe->front = pNode;
    }else{
        qe->rear->pNext = pNode; // node 添加在链表的末端
    }
    // 需要保存队列的最后地址
    qe->rear = pNode;
    // 队列中的节点数量增加
    qe->itemNum++;

    return 0;
}

/* 从队列首端清除一个Item,成功返回0,否则返回其他数 */
/* 队列中第一个Item复制到外部,然后删除队列中的item */
unsigned int DeleteFirstItemQueue(Item* item, Queue* qe)
{
    Node* pTmp;
    if(QueueIsEmpty(qe))
        return 1;// 队列为空
    *item = qe->front->item;  // 将数据返回到外部

    pTmp = qe->front;
    qe->front = qe->front->pNext;
    free(pTmp);   // 释放掉节点
    qe->itemNum--;
    if(QueueIsEmpty(qe))
        qe->rear = NULL;

    return 0;
}

/* 清空队列 */
void EmptyQueue(Queue * qe)
{
    Item item;
    while(QueueIsEmpty(qe))
        DeleteFirstItemQueue(&item, qe);
}
View Code
复制代码

  队列接口测试:

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "myQueue.h"

int main()
{
    Queue line;
    Item item;
    char ch;

    InitalizeQueue(&line);
    puts("Test queue interface, Type a to add item, Type d to delete item");
    puts("Type q to exit program");

    
    while( (ch= getchar()) !=  'q')
    {
        
        if(ch != 'a' && ch!= 'd')
        {    if(ch == 'q')
                break;
            continue;
        }
        if(ch == 'a')
        {
            // 添加元素
            printf("Interge to add:\n");
            scanf("%d", &item);
            if(!QueueIsFull(&line))  // 队列非满
            {
                printf("add item %d into queue",item);
                AddItemEndQueue(item,&line);
            }else{ // 队列满了
                puts("queue is full");
            }

        }else{
            // 删除元素
            if(QueueIsEmpty(&line))
                puts("Nothing to delete");
            else{
                DeleteFirstItemQueue(&item, &line);
                printf("Remove item %d from queue", item);
            }
        }
        printf("%d items in the queue\n", GetQueueItemCount(&line));
        puts("Type a to add item, d to delete item, q to quit");

    }
    EmptyQueue(&line);
    puts("Bye...\n");
    getchar();


    return 0;
}
View Code
复制代码

 

8、二叉树

1、接口封装

复制代码
#ifndef __TREE_H__
#define __TREE_H__

typedef struct item{
    char PetName[16];
    char PetKind[16];
}Item;

typedef struct node{
    Item item;
    struct node* Lift;
    struct node* Right;
}Node;

typedef struct tree{
    Node *Root;
    int size;
}Tree;

#define MAXITEM 10

/* 初始化树为空树 */
void InitTree(Tree* tree);

/* 判断树是否为空 空:0,非空:1*/
unsigned int TreeIsEmpty(const Tree* tree);

/* 判断树是否为满 满:0,非满:1*/
unsigned int TreeIsFull(const Tree* tree);

/* 获取树中,项目节点的个数 */
unsigned int TreeGetItemCount(const Tree* tree);

/* 向树中添加一个节点项目 */
unsigned int TreeAddItem(const Item* item, Tree* tree);

/* 在树中查找一个节点项目 */
unsigned int TreeFindItem(const Item* item, const Tree* tree);

/* 在树中删除一个节点项目 */
unsigned int TreeDeleteItem(Item* item, Tree* tree);

/* 把一个函数作用于树中所有项目 */
unsigned int TreeTraverseItem(Tree* tree, void (*pFunc)(Item *item));

/* 删除树中所有节点 */
void TreeDelAllItem(Tree* tree);

#endif
View Code
复制代码

2、接口实现

复制代码
#include <stdio.h>
#include <stdlib.h>
#include "Tree.h"

/*
二叉树的属性:
    1、

*/

typedef struct pair{
    Node* child;
    Node* parent;
}Pair;

static Node* MakeNode(const Item* item)
{
    Node* pNode;
    pNode = (Node*)malloc(sizeof(Node));
    if(pNode != NULL){
        pNode->Lift = NULL;
        pNode->Right = NULL;
        pNode->item = *item;
    }
    return pNode;
}

// 判断树中是否已经有将要添加的新节点
static Pair SeekItem(const Item* item, const Tree* tree)
{

}

static unsigned int TreeAddNode(const Item* item, const Node* node)
{
    return 0;
}


/* 初始化树为空树 */
void InitTree(Tree* tree)
{

}
/* 判断树是否为空 空:0,非空:1*/
unsigned int TreeIsEmpty(const Tree* tree)
{
    return 0;
}

/* 判断树是否为满 满:0,非满:1*/
unsigned int TreeIsFull(const Tree* tree)
{
    return 0;
}

/* 获取树中,项目节点的个数 */
unsigned int TreeGetItemCount(const Tree* tree)
{
    return 0;
}

/* 在树中添加项目节点 */
unsigned int TreeAddItem(const Item* item, Tree* tree)
{
    Node* newNode;
    // 判断树中是否有节点空位
    if(TreeIsFull(tree))
    {
        printf("the tree is full \n");
        return -1;
    }
    // 判断树中是否已经有将要添加的节点
    if(SeekItem(item, tree).child != NULL)
    {
        printf("attemp");
        return -2;
    }
    // 创建新节点,并幅值左右节点
    newNode = MakeNode(item);
    if(newNode == NULL)
    {
        printf("create new Node failed\n");
        return -3;
    }
    // 成功创建新节点
    tree->size++;
    if(tree->Root == NULL) // 空树
        tree->Root = newNode;
    else
        TreeAddNode(item,tree->Root);

    return 0;
}

/* 在树中寻找项目节点 */
unsigned int TreeFindItem(const Item* item, const Tree* tree)
{
    return 0;
}

/* 树中删除项目节点 */
unsigned int TreeDeleteItem(Item* item, Tree* tree)
{
    return 0;
}

/* 将一个函数作用于所有节点 */
unsigned int TreeTraverseItem(Tree* tree, void (*pFunc)(Item *item))
{
    return 0;
}

/* 删除树中所有节点 */
void TreeDelAllItem(Tree* tree)
{

}
View Code
复制代码

3、接口测试

复制代码
#include <stdio.h>
#include "Tree.h"

int main()
{

    return 0;
}
View Code
复制代码

 

posted @   笑不出花的旦旦  阅读(118)  评论(0)    收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示