十一、实现队列的方法二(单链表的复用)

通过对单链表代码的复用,实现队列

一、LinkList.h

#ifndef _LINKLIST_H_

#define _LINKLIST_H_

typedef void LinkList;

typedef struct _tag_LinkListNode LinkListNode;

struct _tag_LinkListNode

{

LinkListNode* next;

};

LinkList* LinkList_Create();

void LinkList_Destroy(LinkList* list);

void LinkList_Clear(LinkList* list);

int LinkList_Length(LinkList* list);

int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);

LinkListNode* LinkList_Get(LinkList* list, int pos);

LinkListNode* LinkList_Delete(LinkList* list, int pos);

#endif

二、LinkList.c

#include <stdio.h>

#include <malloc.h>

#include "LinkList.h"

typedef struct _tag_LinkList

{

LinkListNode header;

int length;

} TLinkList;

LinkList* LinkList_Create() // O(1)

{

TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));

if( ret != NULL )

{

ret->length = 0;

ret->header.next = NULL;

}

return ret;

}

void LinkList_Destroy(LinkList* list) // O(1)

{

free(list);

}

void LinkList_Clear(LinkList* list) // O(1)

{

TLinkList* sList = (TLinkList*)list;

if( sList != NULL )

{

sList->length = 0;

sList->header.next = NULL;

}

}

int LinkList_Length(LinkList* list) // O(1)

{

TLinkList* sList = (TLinkList*)list;

int ret = -1;

if( sList != NULL )

{

ret = sList->length;

}

return ret;

}

int LinkList_Insert(LinkList* list, LinkListNode* node, int pos) // O(n)

{

TLinkList* sList = (TLinkList*)list;

int ret = (sList != NULL) && (pos >= 0) && (node != NULL);

int i = 0;

if( ret )

{

LinkListNode* current = (LinkListNode*)sList;

for(i=0; (i<pos) && (current->next != NULL); i++)

{

current = current->next;

}

node->next = current->next;

current->next = node;

sList->length++;

}

return ret;

}

LinkListNode* LinkList_Get(LinkList* list, int pos) // O(n)

{

TLinkList* sList = (TLinkList*)list;

LinkListNode* ret = NULL;

int i = 0;

if( (sList != NULL) && (0 <= pos) && (pos < sList->length) )

{

LinkListNode* current = (LinkListNode*)sList;

for(i=0; i<pos; i++)

{

current = current->next;

}

ret = current->next;

}

return ret;

}

LinkListNode* LinkList_Delete(LinkList* list, int pos) // O(n)

{

TLinkList* sList = (TLinkList*)list;

LinkListNode* ret = NULL;

int i = 0;

if( (sList != NULL) && (0 <= pos) && (pos < sList->length) )

{

LinkListNode* current = (LinkListNode*)sList;

for(i=0; i<pos; i++)

{

current = current->next;

}

ret = current->next;

current->next = ret->next;

sList->length--;

}

return ret;

}

三、LinkQueue.h

#ifndef _LINKQUEUE_H_

#define _LINKQUEUE_H_

typedef void LinkQueue;

LinkQueue* LinkQueue_Create();  //创建队列

void LinkQueue_Destroy(LinkQueue* queue);  //销毁队列

void LinkQueue_Clear(LinkQueue* queue);   //清空队列

int LinkQueue_Append(LinkQueue* queue, void* item);   //进队列

void* LinkQueue_Retrieve(LinkQueue* queue);      //出队列

void* LinkQueue_Header(LinkQueue* queue);    //获取队列头元素

int LinkQueue_Length(LinkQueue* queue);  //获取队列当前元素个数

#endif

四、LinkQueue.c

#include <malloc.h>

#include "LinkList.h"

#include "LinkQueue.h"

typedef struct _tag_LinkQueueNode

{

LinkListNode header;

void* item;

} TLinkQueueNode;

LinkQueue* LinkQueue_Create() // O(1)

{

return LinkList_Create();

}

void LinkQueue_Destroy(LinkQueue* queue) // O(n)

{

LinkQueue_Clear(queue);

LinkList_Destroy(queue);

}

void LinkQueue_Clear(LinkQueue* queue) // O(n)

{

while( LinkQueue_Length(queue) > 0 )  // 判断当前的元素是否为 0,不为0,执行出队列

{

LinkQueue_Retrieve(queue);

}

}

int LinkQueue_Append(LinkQueue* queue, void* item) // O(n)

{

TLinkQueueNode* node = (TLinkQueueNode*)malloc(sizeof(TLinkQueueNode));  //分配内存

int ret = (item != NULL) && (node != NULL);   //判断头节点指向的地址和进队列的地址是否合法

if( ret )

{

node->item = item;//将入队列的元素赋值 给node

ret = LinkList_Insert(queue, (LinkListNode*)node, LinkList_Length(queue));//插入到队列末尾

}

if( !ret )

{

free(node);

}

return ret;

}

void* LinkQueue_Retrieve(LinkQueue* queue) // O(1)

{

TLinkQueueNode* node = (TLinkQueueNode*)LinkList_Delete(queue, 0);  //将队列的删除的第一个元素赋值给ret,然后清空node空间,返回删除的元素

void* ret = NULL;

if( node != NULL )

{

ret = node->item;

free(node);

}

return ret;

}

void* LinkQueue_Header(LinkQueue* queue) // O(1)

{

TLinkQueueNode* node = (TLinkQueueNode*)LinkList_Get(queue, 0);

void* ret = NULL;

if( node != NULL )

{

ret = node->item;

}

return ret;

}

int LinkQueue_Length(LinkQueue* queue) // O(1)

{

return LinkList_Length(queue);

}

五、main.c

#include <stdio.h>

#include <stdlib.h>

#include "LinkQueue.h"

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[])

{

LinkQueue* queue = LinkQueue_Create();

int a[10] = {0};

int i = 0;

for(i=0; i<10; i++)

{

a[i] = i + 1;

LinkQueue_Append(queue, a + i);

}

printf("Header: %d\n", *(int*)LinkQueue_Header(queue));

printf("Length: %d\n", LinkQueue_Length(queue));

while( LinkQueue_Length(queue) > 0 )

{

printf("Retrieve: %d\n", *(int*)LinkQueue_Retrieve(queue));

}

LinkQueue_Destroy(queue);

return 0;

}

时间: 2024-09-28 05:27:13

十一、实现队列的方法二(单链表的复用)的相关文章

C++ 数据结构学习二(单链表)

模板类 //LinkList.h 单链表#ifndef LINK_LIST_HXX#define LINK_LIST_HXX#include <iostream>using namespace std; template<class T>struct Node{ T data; Node * next;}; template<class T>class LinkList{ public: LinkList(); //无参构造函数,建立只有头结点的空链表 LinkList

两种方法求单链表逆序

1 递归,非常easy 代码: #include<iostream> using namespace std; typedef struct node{ int data; struct node * pNext; }Node ,*pNode; void createNode(pNode & pHead){ int temp; scanf("%d",&temp); pNode p,q; bool isFirst = true; while(temp){ if

对带头结点的单链表的简单操作

#pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<memory.h> #define DataType int           //int 可以改写为其它数据类型 typedef struct Node { DataType data; struct Node *next; }Node,*pNode;          //定义结点结构体      

04.线性表(三)链式存储结构.单链表2

链式存储结构.单链表2 顺序存储结构的创建实质是一个数组的初始化,存储空间连续且其大小和类型已经固定:单链表存储空间不连续,是一种动态结构且它所占用空间的大小和位置是不需要预先分配划定的,可以根据系统的情况和实际的需求即时生成. 一.单链表的整表创建 创建单链表的过程就是一个动态生成链表的过程,即从"空表"的初始化起,依次建立各元素结点,并逐个插入链表. 1.算法思路 (1)声明一个结点p和计数器变量i; (2)初始化一空链表L (3)让链表L的头结点的指针指向NULL,即建立一个带头

C#单链表(数据结构)

学习单链表的源码项目:http://files.cnblogs.com/xmfdsh/CSharp%E5%8D%95%E9%93%BE%E8%A1%A8.rar 链表是用一组任意的存储单元来存储线性表中的数据元素(在存储单元中可以是连续的,也可以是不连续的).链表在存储数据元素时,除了存储数据元素本身的信息外,还要存储与它相邻的数据元素的存储地址信息.这两部分信息组成该数据元素的存储映像,称为节点. 节点的形象图如下: 首先定义一个类Node来表示这些节点: public class Node<

再谈单链表

#pragma once #include<stdio.h> #include<string.h> #include<assert.h> #include <stdlib.h> typedef int DataType; //定义一个结构体类型 typedef struct LinkNode { DataType data;//定义节点的数据 struct LinkNode *next;//保存下一个类型节点的地址 }LinkNode, *pLinkNode

递归实现单链表的各种基本操作

1 #include<iostream> 2 using namespace std; 3 4 #define OK 1 5 #define ERROR 0 6 typedef int Status; 7 8 typedef struct LNode 9 { 10 int data; //结点的数据域 11 struct LNode *next; //结点的指针域 12 }LNode, *LinkList; //LinkList为指向结构体LNode的指针类型 13 14 void creat

图解单链表反转

仅一家之言,望多交流,如有错漏,还请指教! 另,做图不易,转发请注明出处 https://www.cnblogs.com/luego/p/11421590.html 本文有要以图的方式,来呈现链表反转推演的具体过程,以助于理解,保持思路的清晰. 主要采用两种方法实现单链表反转: (1)通过循环,通过三个指针对链表进行遍历,并逐个反转: (2)使用递归的方法进行反转.  1. 循环反转 废话不多说,先上图: 操作过程: ① 初始化pNext至当前节点的下一个节点,为断链做准备② 判断下一个节点是否

单链表逆序的几种方法

假设单链表数据结构定义如下: struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; 单链表有一个头指针指向第一个结点,最后一个结点指向NULL 一.最容易想到的方法,新建一个单链表newNode,每次将原先链表的第一个结点放到newNode后 ListNode* reverseList(ListNode* head) { ListNode *newNode = new ListN