创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥专栏汇总:全部文章专栏汇总 🔥
给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ
目录
本文基于链表的基础知识之上, 将常用的链表函数功能 汇总
一、组件化封装的意义
组件化封装就是将平时常用的一些函数,根据经验归纳总结到一个文件中,便于以后再次使用。
1.提升代码复用性:组件化封装可以将一些通用的、经常使用的功能和界面进行封装,以供其他模块或项目复用,减少重复工作,提升开发效率。
2.降低维护成本:组件化封装使代码模块化,一旦封装好了某一个功能或界面,就可以在不同的项目中复用。这样可以减少代码冗余,降低维护成本。
3.提高代码可读性和可维护性:不同的组件之间有着清晰的接口和依赖关系,代码的逻辑更加清晰,易于维护和扩展。
4.促进团队合作。
二、链表的增删改查 组件化封装:
总代码文件:
头文件linkedlist.h:
#pragma once
#include <stdio.h>
#include <stdlib.h>
/*节点结构体*/
typedef struct node
{
struct node *prev;
void * data;
struct node *next;
} Node , * PNode;
/*链表结构体*/
typedef struct
{
PNode header;
PNode ender;
int size;
PNode nextNode;//迭代器的下一个节点
}LinkedList ,* PLinkedList ;
/*创建链表*/
PLinkedList createLinkedList();
/*创建节点*/
PNode createNode( void * data);
/*增加新的节点*/
void add(PLinkedList list , void * data);
/*在某节点的位置上插入新节点*/
void insert(PLinkedList list ,int index, void * data);
/*删除 指定 下标的节点*/
void* removeIndex(PLinkedList list ,int index);
/*删除等于参数的首个节点*/
void removeData(PLinkedList list , void* data);
/*某下标对应的 节点*/
void* get(PLinkedList list ,int index);
/*找到节点*/
PNode findNode(PLinkedList list ,int index);
/*某下标对应的 节点数据进行更新 */
void set(PLinkedList list ,int index, void* newdata);
/*某数据对应的下标*/
int indexOf(PLinkedList list , void* data);
/*节点数量*/
int size(PLinkedList list );
/*清空链表*/
void clear(PLinkedList list );
/*迭代器*/
//产生新的迭代器
void iterator(PLinkedList list);
//是否有下一个节点
int hasNext(PLinkedList list);
//取得下一个节点数据
void* next(PLinkedList list);
/*实现栈stack的功能:LIFO:last in first out */
/* 入栈*/
void push(PLinkedList list , void* data);
/*出栈*/
void* pop(PLinkedList list );
/*实现队列queue的功能:FIFO:first in first out */
void addFirst(PLinkedList list , void* data);
void addLast(PLinkedList list , void* data);
void* removeFirst(PLinkedList list);
void* removeLast(PLinkedList list);
源文件LinkedList.cpp :
#include "linkedlist.h"
PLinkedList createLinkedList()
{
PLinkedList newList =(PLinkedList) malloc(sizeof(LinkedList));
newList->header = NULL;
newList->ender = NULL;
newList->size = 0;
newList->nextNode = NULL;
return newList;
}
PNode createNode(void* data)
{
PNode newNode = (PNode)malloc( sizeof(Node));
newNode->prev = NULL;
newNode->data = data;
newNode->next = NULL;
return newNode;
}
void add(PLinkedList list, void* data)
{
PNode newNode =createNode(data);
if (list->size==0)//空链表
{
list->header = newNode;
list->ender = newNode;
}
else
{
list->ender->next = newNode;
newNode->prev = list->ender;
list->ender = newNode;
}
list->size++;
}
void insert(PLinkedList list, int index, void* data)
{
if ( index>= list->size )//追加到尾部
{
add(list, data);
return;
}
PNode newNode = createNode(data);
//插入到头部
if (index <=0 )
{
newNode->next = list->header;
list->header->prev = newNode;
list->header = newNode;
}
else
{
//1 理想的中间插入
PNode p = findNode(list, index);
PNode q = p->prev;
newNode->next = p;
p->prev = newNode;
newNode->prev = q;
q->next = newNode;
}
list->size++;
}
void* removeIndex(PLinkedList list, int index)
{
PNode p = NULL;//指向被删除的节点
if (list->size==1)//唯一节点
{
p = list->header;
list->header = list->ender = NULL;
}
else if ( index<=0 )
{
p = list->header;
list->header = p->next;
list->header->prev = NULL;
}
else if ( index>=list->size-1)
{
p = list->ender;
list->ender = p->prev;
list->ender->next = NULL;
}
else
{
//理想的中间删除
p = findNode(list, index);
PNode q = p->prev;
PNode m = p->next;
q->next = m;
m->prev = q;
}
if (p!=NULL)
{
void* tdata = p->data;
free(p);
list->size--;
return tdata;
}
return NULL;
}
void removeData(PLinkedList list, void* data)
{
int i=indexOf(list, data);
if (i>=0)
{
removeIndex(list, i);
}
}
void* get(PLinkedList list, int index)
{
PNode p = findNode(list, index);
if (p)
{
return p->data;
}
return NULL;
}
PNode findNode(PLinkedList list, int index)
{
PNode p = list->header;
for (int i=0 ;i<index ;i++ )
{
p = p->next;
}
return p;
}
void set(PLinkedList list, int index, void* newdata)
{
PNode p=findNode(list, index);
if (p)
{
p->data = newdata;
}
}
int indexOf(PLinkedList list, void* data)
{
int i = 0;
iterator(list);
while ( hasNext(list))
{
if ( next(list)== data)
{
return i;
}
i++;
}
return -1;
}
int size(PLinkedList list)
{
return list->size;
}
void clear(PLinkedList list)
{
PNode p = list->header;
PNode q;
while (p)
{
q = p;
p = p->next;
free(q);
}
list->header = NULL;
list->ender = NULL;
list->size = 0;
}
void iterator(PLinkedList list)
{
list->nextNode = list->header;
}
int hasNext(PLinkedList list)
{
return list->nextNode!=NULL;
}
void* next(PLinkedList list)
{
void* data = list->nextNode->data;
list->nextNode = list->nextNode->next;//为下一次做准备
return data;
}
void push(PLinkedList list, void* data)
{
add(list, data);
}
void* pop(PLinkedList list)
{
return removeIndex(list,list->size-1);
}
void addFirst(PLinkedList list, void* data)
{
insert(list, 0, data);
}
void addLast(PLinkedList list, void* data)
{
add(list, data);
}
void* removeFirst(PLinkedList list)
{
return removeIndex(list,0);
}
void* removeLast(PLinkedList list)
{
return removeIndex(list,list->size-1);
}
用例测试文件useLinkedList.cpp :
对LinkedList中实现功能的函数进行用例测试
#include "linkedlist.h"
#include "string.h"
/*数据域*/
typedef struct
{
int data;
} Data,*PData;
/*创建数据域*/
PData createData(int d);
int main()
{
PLinkedList list = createLinkedList();
add(list, "张三");//0
add(list, "李四");//1
add(list, "旺旺");//2
add(list, "天喜");//3
add(list, "椰子");//4
set(list, 1, "路飞");
printf("下标:%d\n", indexOf(list,"天喜"));
//removeData(list, "李四");
//insert(list, 3, "咖啡");
//insert(list, 8, "末尾");
//insert(list, 0, "开头");
/*printf("%s\n",(const char*) removeIndex(list, 2));
printf("%s\n", (const char*)removeIndex(list, 4));
printf("%s\n", (const char*)removeIndex(list, 0));*/
//下标遍历
//for (int i=0 ;i<size(list); i++)//
//{
// const char * str = (const char*)get(list, i);
// printf("%s\n",str);
//}
/*PNode p = list->header;
while (p)
{
printf("%s\n", (const char*)p->data);
p=p->next;
}*/
//iterator(list);
//while ( hasNext(list) )
//{
// printf("%s\n", (const char*) next(list));
//}
释放链表
//clear(list);
//free(list);
//list = NULL;
//PLinkedList list1 = createLinkedList();
//PLinkedList list2 = createLinkedList();
//PLinkedList stack = createLinkedList();
//push(stack, "aa");
//push(stack, "bb");
//push(stack, "cc");
//push(stack, "dd");
//
//printf("%s\n", (const char*)pop(stack));//dd
//printf("%s\n", (const char*)pop(stack));
//printf("%s\n", (const char*)pop(stack));
//printf("%s\n", (const char*)pop(stack));
//PLinkedList queue = createLinkedList();
//addFirst(queue, "aa");
//addFirst(queue, "bb");
//addFirst(queue, "cc");
//addFirst(queue, "dd");
//printf("%s\n", (const char*)removeLast(queue));
//printf("%s\n", (const char*)removeLast(queue));
//printf("%s\n", (const char*)removeLast(queue));
//printf("%s\n", (const char*)removeLast(queue));
return 0;
}
PData createData(int d)
{
PData pd = (PData)malloc(sizeof( Data));
pd->data= d;
return pd;
}
就是在同一项目下建立一个测试用的文件,输入函数的定义进行功能测试:
如果达到了预期效果,该函数就是编写成功
三、交换、打乱、排序、查找等功能
总代码文件:
头文件collections.h
#pragma once
#include <time.h>
#include "linkedlist.h"
/*定义一个可指向比较函数的函数指针
此函数用于用户自定义结构数据的比较
比较结果分为
大于0 等于0 和小于0来表达两个参数的大小关系
*/
typedef int(*Compare)( void*, void *);
/*将链表2 追加到链表1的后面*/
void addAll__(PLinkedList list1, PLinkedList list2);
/*返回最大数据域*/
void* max__(PLinkedList list,Compare fun);
/*返回最小数据域*/
void* min__(PLinkedList list,Compare fun);
/*交换 两个下标对应的数据域*/
void swap__(PLinkedList list, int i, int j);
/*对链表 按 Compare比较规则 进行排序 */
void sort__(PLinkedList list,Compare fun );
/*使用折半查找思路 查询某key数据的下标*/
int binarySearch__(PLinkedList list, void * key, Compare fun);
/*打乱链表的顺序*/
void shuffle__(PLinkedList list);
/*对链表成员进行首尾倒置*/
void reverse__(PLinkedList list);
/*把符合fun比较规则的数据域 替换成新的数据域*/
void replaceAll__(PLinkedList list, void *oldVal, void *newVal, Compare fun );
源文件Collection.cpp :
#include "collections.h"
#include "linkedlist.h"
void addAll__(PLinkedList list1, PLinkedList list2)
{
//方案1
/*list1->ender->next = list2->header;
list2->header->prev = list1->ender;
list1->size += list2->size;*/
//方案2
iterator(list2);
while ( hasNext(list2))
{
add(list1, next(list2));
}
}
void* max__(PLinkedList list, Compare fun)
{
void* max_value = list->header->data;
PNode p = list->header->next;
while (p!=NULL)
{
if ( fun(max_value, p->data) <0)
{
max_value = p->data;
}
p = p->next;
}
return max_value;
}
void* min__(PLinkedList list, Compare fun)
{
void* min_value = list->header->data;
PNode p = list->header->next;
while (p != NULL)
{
if (fun(min_value, p->data) > 0)
{
min_value = p->data;
}
p = p->next;
}
return min_value;
}
void swap__(PLinkedList list, int i, int j)
{
PNode p_i = findNode(list, i);
PNode p_j = findNode(list, j);
void* t;
t = p_i->data;
p_i->data = p_j->data;
p_j->data = t;
}
void sort__(PLinkedList list, Compare fun)
{
for (int suo=0 ;suo<size(list)-1 ;suo++ )
{
for (int bi=suo+1 ;bi<size(list) ;bi++ )
{
if ( fun( get(list,suo),get(list,bi))>0 )
{
swap__(list,suo,bi);
}
}
}
}
int binarySearch__(PLinkedList list, void* key, Compare fun)
{
int left = 0;
int right = size(list) - 1;
int mid;
do
{
mid = (left + right) / 2;
void* mid_data = get(list,mid);
int cmp = fun(mid_data, key);
if ( cmp==0 )
{
return mid;
}
else if (cmp >0 )
{
right = mid - 1;
}
else
{
left = mid + 1;
}
} while (left<=right);
return -mid;
}
void shuffle__(PLinkedList list)
{
srand((unsigned)time(NULL));
for (int i=0 ; i<size(list) ; i++)
{
int m = rand() % size(list);
int n = rand() % size(list);
swap__(list, m, n);
}
}
void reverse__(PLinkedList list)
{
void* t;
int i = 0, j=size(list)-1;
for (PNode left = list->header,right = list->ender ; i<j ;left=left->next,right=right->prev,i++,j-- )
{
t = left->data;
left->data = right->data;
right->data = t;
}
}
void replaceAll__(PLinkedList list, void* oldVal, void* newVal, Compare fun)
{
PNode p = list->header;
while ( p )
{
if ( fun( oldVal,p->data)==0)
{
p->data = newVal;
}
p = p->next;
}
}
四、 本文中所有函数功能列表:
以下是本文代码文件中涉及的功能:
-
创建链表
-
创建节点
-
增加新的节点
-
在某个位置插入新节点
-
删除指定下标的节点
-
删除等于参数的首个节点
-
通过下标获取节点
-
通过数据查找相应节点并返回节点数据
-
对某个下标的节点进行更新
-
获取某个数据的下标
-
获取链表中的节点数量
-
清空链表
-
迭代器:生成迭代器,判断是否有下一个节点,取得下一个节点的数据
-
实现栈 stack 的功能:添加元素、弹出元素
-
实现队列 queue 的功能:在链表头尾添加元素,从头或尾移除元素
-
addAll__:将链表2 追加到链表1的后面
-
max__:返回链表中最大的数据域
-
min__:返回链表中最小的数据域
-
swap__:交换链表中两个下标对应的数据域
-
sort__:对链表按照指定比较规则进行排序
-
binarySearch__:使用折半查找思路在链表中查找某个key的数据域并返回其下标
-
shuffle__:随机打乱链表中元素的顺序
-
reverse__:将链表中的成员进行首尾倒置
-
replaceAll__:将符合指定比较规则的数据域替换为新的数据域
本链表的增删改查功能组件可以被复用在平时的项目中。
大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。 |
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●) |