链表功能组件化

链表组件化分为三个步骤:

第一步:规划函数功能;

第二步:对函数功能进行定义实现;

第三步:对函数进行测试驱动;

编写链表功能组件化首先应在Visual-Studio中创建链表组件化项目,在头文件处创建linkedlist.h和collections.h文件,在源文件中创建Collections.cpp和LinkedList.cpp功能文件与三个测试文件。

 

在头文件 linkedlist.h中定义链表的添加、删除、清空、修改、按下标查找、按数据查找、栈实现、队列实现等功能,在collections.h中定义链表的排序、交换、打乱、最大最小值等功能。

下面我们先编写 linkedist.h文件中的函数功能,如图所示:

 1./*创建链表*/
PLinkedList createLinkedList();

PLinkedList createLinkedList()
{
	PLinkedList newList = (PLinkedList)malloc(sizeof(LinkedList));
	if (newList!=NULL)
	{
		newList->header = NULL;
		newList->ender = NULL;
		newList->size = 0;
		newList->nextNode = NULL;
	}
	return  newList;
}

 2./*创建节点*/
PNode createNode(  void * data);

PNode createNode(void* data)
{
	PNode newnode = (PNode)malloc(sizeof(Node));
	newnode->prev = NULL;
	newnode->next = NULL;
	newnode->data = data;
	return newnode;
}

3./*增加新的节点*/
void add(PLinkedList  list ,  void * data);

void add(PLinkedList list, void* data)
{
	PNode newNode=createNode(data);
	if (list->size==0)//空链表
	{
		list->header = list->ender = newNode;
	}
	else
	{
		list->ender->next = newNode;
		newNode->prev = list->ender;
		list->ender = newNode;
	}
	list->size++;
}

4./*在某节点的位置上插入新节点*/
void insert(PLinkedList  list ,int index,  void * data);

void insert(PLinkedList list, int index, void* data)
{//空链表                 //插入尾部
	if (list->size==0 || 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
	{
		//理想的 中间插入
		PNode p = findNode(list, index);
		PNode q = p->prev;//插入点的前面的节点
		newnode->next = p;
		p->prev = newnode;
		q->next = newnode;
		newnode->prev = q;
	}
	list->size++;
}

5./*删除 指定 下标的节点*/
void* removeIndex(PLinkedList  list ,int index);

void* removeIndex(PLinkedList list, int index)
{
	if (list->size==0)
	{
		return NULL;
	}
	PNode p =NULL;//p指向被删除的节点
	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* temp = p->data;
		free(p);
		list->size--;
		return temp;
	}
	return NULL;
}

6./*删除等于参数的首个节点*/
void removeData(PLinkedList  list ,  void* data, Compare fun);

这里函数中有函数参数,这里是比较函数,定义两个void*类型的参数在定义的函数内转换要比较类型,然后比较;具如图所示:

在主函数测试函数中加入比较函数即可; 

 

void removeData(PLinkedList list, void* data, Compare fun)
{
	int i=indexOf(list, data,fun);
	if (i>=0)
	{
		removeIndex(list, i);
	}
}

7./*某下标对应的 节点*/
void* get(PLinkedList  list ,int index);

void* get(PLinkedList list, int index)
{
	PNode p = findNode(list, index);
	return p!=NULL? p->data : NULL;
}

8./*找到节点*/
PNode findNode(PLinkedList  list ,int index);

PNode findNode(PLinkedList list, int index)
{
	PNode p = list->header;
	for (int i = 0; i < index; i++)
	{
		p = p->next;
	}
	return p;
}

9./*某下标对应的 节点数据进行更新 */
void set(PLinkedList  list ,int index,  void* newdata);

void set(PLinkedList list, int index, void* newdata)
{
	PNode p=findNode(list, index);
	if ( p!=NULL)
	{
		p->data = newdata;
	}
}

10./*某数据对应的下标*/
int indexOf(PLinkedList  list , void* data,Compare fun );

int indexOf(PLinkedList list, void* data, Compare fun)
{
	iterator(list);
	for (int i=0 ;hasNext(list) ;i++ )
	{
		//if ( next(list)== data)
		if ( fun(next(list), data)==0 )
		{
			return i;
		}
	}
	return -1;
}

11./*节点数量*/
int size(PLinkedList  list );

int size(PLinkedList list)
{
	return list->size;
}

12./*清空链表*/
void clear(PLinkedList  list );

 

void clear(PLinkedList list)
{
	PNode p = list->header;
	PNode q = NULL;
	while (p!=NULL)
	{
		q = p;
		p = p->next;
		free(q);
	}
	list->header = list->ender = NULL;
	list->size = 0;
}

13.迭代器

//产生新的迭代器
void iterator(PLinkedList list);
//是否有下一个节点
int hasNext(PLinkedList list);
//取得下一个节点数据
void* next(PLinkedList list);

void iterator(PLinkedList list)
{
	list->nextNode = list->header;
}

int hasNext(PLinkedList list)
{
	return list->nextNode!= NULL;
}

void* next(PLinkedList list)
{
	if (list->nextNode!=NULL)
	{
		void* data = list->nextNode->data;
		//为下一次做准备
		list->nextNode = list->nextNode->next;
		return data;
	}
	return NULL;
}

14.实现栈stack功能,满足LIFO原则:后入先出;

/* 入栈*/
void push(PLinkedList  list ,  void* data);

/*出栈*/
void* pop(PLinkedList  list );

void push(PLinkedList list, void* data)
{
	add(list, data);
}

void* pop(PLinkedList list)
{
	return removeIndex(list,size(list)-1);
}

15.实现队列queue功能,满足FIFO原则:先进先出;

void addFirst(PLinkedList  list ,  void* data);
void addLast(PLinkedList  list ,  void* data);
void* removeFirst(PLinkedList  list   );
void* removeLast(PLinkedList  list  );

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, size(list)-1);
}

然后编写collections.h文件的函数功能,如图所示:

 1./*将链表2 追加到链表1的后面*/
void  addAll__(PLinkedList list1, PLinkedList list2);

void addAll__(PLinkedList list1, PLinkedList list2)
{
	iterator(list2);
	while (hasNext(list2))
	{
		add(list1, next(list2));
	}
}

2./*返回最大数据域*/
void*  max__(PLinkedList list,Compare fun);

void* max__(PLinkedList list, Compare fun)
{
	if (list->size == 0)return NULL;
	void* maxValue = list->header->data;
	iterator(list);
	while (hasNext(list))
	{
		void* data =next(list);
		if (  fun(maxValue,data)<0 )
		{
			maxValue = data;
		}
	}
	return maxValue;
}

3./*返回最小数据域*/
void*  min__(PLinkedList list,Compare fun);

void* min__(PLinkedList list, Compare fun)
{
	if (list->size == 0)return NULL;
	void* min_value = get(list, 0);
	for (int i=1 ;i<size(list) ;i++ )
	{
		void* data = get(list, i);
		if ( fun(min_value, data)>0)
		{
			min_value = data;
		}
	}
	return min_value;
}

4./*交换 两个下标对应的数据域*/
void swap__(PLinkedList list, int i, int j);

void swap__(PLinkedList list, int i, int j)
{
	PNode pi = findNode(list, i);
	PNode pj = findNode(list, j);
	void* t;
	t = pi->data;
	pi->data = pj->data;
	pj->data = t;
}

5./*对链表 按 Compare比较规则 进行排序 */
void sort__(PLinkedList list,Compare fun );

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);
	//		}
	//	}
	//}
	PNode p_suo = list->header;
	PNode p_bi =NULL;
	for (int suo = 0; suo < size(list) - 1; suo++)
	{
		p_bi = p_suo->next;
		for (int bi = suo + 1; bi < size(list); bi++)
		{
			if( fun(p_suo->data,p_bi->data)>0)
			{
				void* t;
				t = p_suo->data;
				p_suo->data = p_bi->data;
				p_bi->data = t;
			}
			p_bi = p_bi->next;
		}
		p_suo = p_suo->next;
	}
}

6./*使用折半查找思路 查询某key数据的下标*/
int binarySearch__(PLinkedList list,   void * key, Compare fun);

int binarySearch__(PLinkedList list, void* key, Compare fun)
{
	int low = 0;
	int high = size(list) - 1;
	int mid;
	do
	{
		mid = (low + high) / 2;
		void* data = get(list, mid);
		int r = fun(data, key);
		if (r==0)
		{
			return mid;
		}
		else if (r<0) {
			low = mid + 1;
		}
		else
		{
			high = mid - 1;
		}

	} while (low<=high);
	return -1;
}

7./*打乱链表的顺序*/
void shuffle__(PLinkedList list);

void shuffle__(PLinkedList list)
{
	srand((unsigned) time(NULL));
	for (int i=0 ;i<size(list) ;i++ )
	{
		int a = rand() % size(list);
		int b = rand() % size(list);
		swap__(list, a, b);
	}
}

8./*对链表成员进行首尾倒置*/
void  reverse__(PLinkedList list);

void reverse__(PLinkedList list)
{
	//for (int i=0,j=size(list)-1 ; i<j; i++,j--)
	//{
	//	swap__(list, i, j);
	//}
	PNode p = list->header;
	PNode q = list->ender;
	void* t;
	for (int i = 0, j = size(list) - 1; i < j; i++, j--)
	{
		t = p->data;
		p->data = q->data;
		q->data = t;
		p = p->next;
		q = q->prev;
	}
 
}

9.*把复合fun比较规则的数据域 替换成新的数据域*/
void replaceAll__(PLinkedList list,  void *oldVal,   void *newVal, Compare fun  );

void replaceAll__(PLinkedList list, void* oldVal, void* newVal, Compare fun)
{
	PNode p = list->header;
	while (p!=NULL)
	{
		if (fun(p->data,oldVal)==0)
		{
			p->data = newVal;
		}
		p = p->next;
	}
}

编写完基本程序检查无误后,打开V-S软件创建新项目选择静态库,名字为StaticListLib;

找到之前编辑的链表功能的文件夹将.p与.cpp功能文件复制,然后右击StaticListLib文件点击添加—>现有项将复制的文件粘贴里然后点击添加;如图所示:

 

然后再下面两个文件的第一行加 #include"pch.h";如图所示:

 然后一般选择在x86系统下点击生成选择生成StaticListLib(U);

 生成完成后,后在窗口显示生成位置;

 将生成的静态库.lib文件复制到刚才的.cpp与.h文件中,将.lib与.h文件复制到新建的测试文件中即可使用;如图所示:

 

 最后在主函数头部添加#pragma comment(lib,".\\StaticListLib.lib"),然后main函数中调用功能函数即可。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力编程的晓宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值