版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/water_3700348/article/details/78191134
优化链表与链队
笔者上一个版本的链表,在尾部插入或删除的操作时,需要使用for循环挪动到尾部,这样时间复杂度就位O(n)。再用其来实现链队的话,那么链队的入队和出队的时间复杂度也会因此受限。如果在链表中加入一个指针,指向尾部元素。那么这个问题就可以迎刃而解。下面是优化过后的链表,和链队的代码。
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#ifndef NULL
#define NULL 0
#endif
/* 元素类型 */
typedef int elem_t;
/* 节点结构体 */
typedef struct _tag_linked_list_node
{
elem_t data;
struct _tag_linked_list_node *next;
}ll_node;
/* 链表结构体 */
typedef struct _tag_linked_list
{
ll_node head; /* 哑结点 */
ll_node *tail; /* 尾部元素指针 */
int length; /* 链表长度 */
}linked_list;
/**
* 创建链表
* @return 返回链表指针,NULL表示创建失败
*/
linked_list *linked_list_create();
/**
* 从头部插入元素
* @param plist 链表指针
* @param pe 被插入元素的指针
* @return 1:成功 0:失败
*/
int linked_list_insert(linked_list *plist,elem_t *pe);
/**
* 从尾部插入元素
* @param plist 链表指针
* @param pe 被插入元素的指针
* @return 1:成功 0:失败
*/
int linked_list_append(linked_list *plist,elem_t *pe);
/**
* 查找元素
* @param plist 链表指针
* @param i 元素位置索引
* @param pe 用于保存被查找元素的值的指针
* @return 1:成功 0:失败
*/
int linked_list_get(linked_list *plist,int i,elem_t *pe);
/**
* 按索引删除元素
* @param plist 链表指针
* @param i 被删除元素的索引
* @param pe 用于保存被删除元素的值的指针
* @return 1:成功 0:失败
*/
int linked_list_remove(linked_list *plist,int i,elem_t *pe);
/**
* 链表反转
* @param plist 链表指针
* @return 1:成功 0:失败
*/
int linked_list_reverse(linked_list *plist);
/**
* 链表合并,将第二个链表链接到第一个链表,第二个链表指针置空
* @param dest 合并的目标链表
* @param pp_src 被合并的链表的指针的指针
* @return 返回合并后的链表的指针(第一个参数)
*/
linked_list *linked_list_merge(linked_list *dest,linked_list **pp_src);
/**
* 获取链表的长度
* @param plist 链表的指针
* @return 返回链表的长度,-1表示出错
*/
int linked_list_length(linked_list *plist);
/**
* 判断链表是否为空
* @param plist
* @return
*/
int linked_list_empty(linked_list *plist);
/**
* 清空链表
* @param plist 链表指针
* @return 1:成功 0:失败
*/
int linked_list_clear(linked_list *plist);
/**
* 销毁链表
* @param plist 链表指针
* @return 1:成功 0:失败
*/
int linked_list_destroy(linked_list *plist);
#endif // LINKEDLIST_H
#include "LinkedList.h"
#include <malloc.h>
/**
* 创建链表
* @return 返回链表指针,NULL表示创建失败
*/
linked_list *linked_list_create()
{
linked_list *plist = (linked_list *)malloc(sizeof(linked_list));
if(plist != NULL)
{
plist->length = 0;
plist->head.next = NULL;
plist->tail = NULL;
}
return plist;
}
/**
* 从头部插入元素
* @param plist 链表指针
* @param pe 被插入元素的指针
* @return 1:成功 0:失败
*/
int linked_list_insert(linked_list *plist,elem_t *pe)
{
int ret = ( (plist != NULL) && (pe != NULL));
if(ret)
{
ll_node *node = (ll_node *)malloc(sizeof(ll_node));
ll_node *head = &(plist->head);
if(node != NULL)
{
node->next = head->next;
head->next = node;
node->data = *pe;
/* 判断是否是第一个元素 */
if(plist->length == 0)
{
/* 尾指针指向第一个元素 */
plist->tail = node;
}
plist->length++;
}
else
{
ret = 0;
}
}
return ret;
}
/**
* 从尾部插入元素
* @param plist 链表指针
* @param pe 被插入元素的指针
* @return 1:成功 0:失败
*/
int linked_list_append(linked_list *plist,elem_t *pe)
{
int ret = ( (plist != NULL) && (pe != NULL));
if(ret)
{
ll_node *node = (ll_node *)malloc(sizeof(ll_node));
if(node != NULL)
{
node->next = NULL;
node->data = *pe;
if(plist->length == 0)
{
plist->tail = node;
plist->head.next = node;
}
else
{
plist->tail->next = node;
plist->tail = node;
}
plist->length++;
}
else
{
ret = 0;
}
}
return ret;
}
/**
* 查找元素
* @param plist 链表指针
* @param i 元素位置索引
* @param pe 用于保存被查找元素的值的指针
* @return 1:成功 0:失败
*/
int linked_list_get(linked_list *plist,int i,elem_t *pe)
{
int ret = ( (plist != NULL) && (pe != NULL) && (i >= 0) && (i < plist->length));
if(ret)
{
int pos = 0;
ll_node *current = plist->head.next;
/* 移动到尾部 */
for(pos = 0;pos < i;pos++)
{
current = current->next;
}
*pe = current->data;
}
return ret;
}
/**
* 按索引删除元素
* @param plist 链表指针
* @param i 被删除元素的索引
* @param pe 用于保存被删除元素的值的指针
* @return 1:成功 0:失败
*/
int linked_list_remove(linked_list *plist,int i,elem_t *pe)
{
int ret = ( (plist != NULL) && (pe != NULL) && (i >= 0) && (i < plist->length));
if(ret)
{
int pos = 0;
ll_node *pre = &(plist->head);
for(pos = 0;pos < i;pos++)
{
pre = pre->next;
}
/* 保存要被删除的元素的值 */
*pe = pre->next->data;
pre->next = pre->next->next;
plist->length--;
}
return ret;
}
/**
* 链表反转
* @param plist 链表指针
* @return 1:成功 0:失败
*/
int linked_list_reverse(linked_list *plist)
{
int ret = (plist != NULL);
if(ret)
{
if(plist->length > 1)
{
ll_node *tail = plist->tail;
/* 将头元素的位置调整到原尾元素的后部插入 */
while(plist->head.next != tail)
{
/* 保存头部元素的指针 */
ll_node *old_head = plist->head.next;
/* 调整头结点指针的位置,指向原头部的下一个元素 */
plist->head.next = old_head->next;
/* 将保存的原头部元素插入到原尾部元素的后面 */
old_head->next = tail->next;
tail->next = old_head;
}
}
}
return ret;
}
/**
* 链表合并,将第二个链表链接到第一个链表,第二个链表指针置空
* @param dest 合并的目标链表
* @param pp_src 被合并的链表的指针的指针
* @return 返回合并后的链表的指针(第一个参数)
*/
linked_list *linked_list_merge(linked_list *dest,linked_list **pp_src)
{
if((dest != NULL) && ( (*pp_src) != NULL) && ((*pp_src)->length != 0))
{
dest->tail->next = (*pp_src)->head.next;
dest->length += (*pp_src)->length;
free(*pp_src);
*pp_src = NULL;
}
return dest;
}
/**
* 获取链表的长度
* @param plist 链表的指针
* @return 返回链表的长度,-1表示出错
*/
int linked_list_length(linked_list *plist)
{
int ret = -1;
if(plist != NULL)
{
ret = plist->length;
}
return ret;
}
/**
* 判断链表是否为空
* @param plist
* @return
*/
int linked_list_empty(linked_list *plist)
{
return (plist->length == 0);
}
/**
* 清空链表
* @param plist 链表指针
* @return 1:成功 0:失败
*/
int linked_list_clear(linked_list *plist)
{
int ret = ((plist != NULL) && (plist->length != 0));
if(ret)
{
ll_node *head = &(plist->head);
while(head->next != NULL)
{
ll_node *del = head->next;
head->next = del->next;
free(del);
}
plist->length = 0;
}
return ret;
}
/**
* 销毁链表
* @param plist 链表指针
* @return 1:成功 0:失败
*/
int linked_list_destroy(linked_list *plist)
{
int ret = (plist != NULL);
if(ret)
{
linked_list_clear(plist);
free(plist);
}
return ret;
}
#ifndef LINKEDQUEUE_H
#define LINKEDQUEUE_H
#include "LinkedList.h"
typedef linked_list linked_queue;
/**
* 创建队列
* @return
*/
linked_queue *linked_queue_create();
/**
* 入队
* @param p 队列指针
* @return 成功:1,失败:0
*/
int linked_queue_enqueue(linked_queue *p,elem_t *pe);
/**
* 出队
* @param p 队列指针
* @return 成功:1,失败:0
*/
elem_t linked_queue_dequeue(linked_queue *p);
/**
* 获取对头元素的值
* @param p 队列指针
* @return
*/
elem_t linked_queue_header(linked_queue *p);
/**
* 获取队列长度
* @param p
* @return
*/
int linked_queue_length(linked_queue *p);
/**
* 队列清空
* @param p
* @return
*/
int linked_queue_clear(linked_queue *p);
/**
* 销毁队列
* @param p
* @return
*/
int linked_queue_destroy(linked_queue *p);
#endif // LINKEDQUEUE_H
#include "LinkedQueue.h"
/**
* 创建队列
* @return
*/
linked_queue *linked_queue_create()
{
return linked_list_create();
}
/**
* 入队
* @param p 队列指针
* @return 成功:1,失败:0
*/
int linked_queue_enqueue(linked_queue *p,elem_t *pe)
{
return linked_list_append(p,pe);
}
/**
* 出队
* @param p 队列指针
* @return 成功:1,失败:0
*/
elem_t linked_queue_dequeue(linked_queue *p)
{
elem_t temp;
linked_list_remove(p,0,&temp);
return temp;
}
/**
* 获取对头元素的值
* @param p 队列指针
* @return
*/
elem_t linked_queue_header(linked_queue *p)
{
elem_t temp;
linked_list_get(p,0,&temp);
return temp;
}
/**
* 获取队列长度
* @param p
* @return
*/
int linked_queue_length(linked_queue *p)
{
return linked_list_length(p);
}
/**
* 队列清空
* @param p
* @return
*/
int linked_queue_clear(linked_queue *p)
{
return linked_list_clear(p);
}
/**
* 销毁队列
* @param p
* @return
*/
int linked_queue_destroy(linked_queue *p)
{
return linked_list_destroy(p);
}