Пример #1
0
void cll_destroy(sb_cll * instance)
{
	while (!cll_empty(instance)) {
		cll_remove(instance);
	}
	free(instance);
}
void Joseph_circle()
{

	//total nodes
	int N=6;

	//the first node (base 1) to count
	int K=1;

	//the turn to move out
	int M=5;

	//create the circle
	cll_node*n=NULL;
	cll_node*knode=NULL;
	for(int i=1;i<=N; i++)
	{
		n=cll_insert_data_after(n,i);
		if(i==K) knode=n;//save the [header] or [current] node your needs.
	}

	bool done=false;
	int i=1;
	while(!done)
	{				
		for(n=knode, i=1; i<M; i++) n = n->next;

		//get the it's next before delete it.
		knode=n->next;

		//the only one node left.
		done= n->next == n;

		//remove out
		std::cout << n->data << " is moved out" << std::endl;
		cll_remove(n);		
	}
}
bool cll_test()
{
	//由于可以通过任何一个节点Next来遍历,因此,在实际应用中,你可能只需要保存一个当前节点,
	//不需要保存每个节点,通过数据来保存每个节点就雷死人了!
	//如果你确实需要一个【头节点-最先加入的节点】/【尾节点-最后加入的节点】,你可以自己保存起来。
	cll_node*n1=NULL;
	cll_node*n2=NULL;
	cll_node*n3=NULL;
	cll_node*n4=NULL;
	cll_node*n5=NULL;
	cll_node*loop=NULL;
	int testcase=0;

	//insert the first node
	testcase=1;
	if((n1=cll_insert_data_after(NULL,1))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after first node failed." << std::endl; 
		return false;
	}
	if(cll_destory(n1)!=1)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}


	//insert 2 nodes
	testcase=2;
	if((n1=cll_insert_data_after(NULL,1))==NULL || (n2=cll_insert_data_after(n1,2))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after 2 nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(n1->next!=n2 || n2->next!=n1) 
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_insert_data_after order error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_destory(n2)!=2)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}


	//insert 3 nodes (1-2-3)-1
	testcase=3;
	if((n1=cll_insert_data_after(NULL,1))==NULL || (n2=cll_insert_data_after(n1,2))==NULL || (n3=cll_insert_data_after(n2,3))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after 3 nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(n1->next!=n2 || n2->next!=n3 || n3->next != n1) 
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_insert_data_after order error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_destory(n2)!=3)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}


	//insert 3 nodes (1-3-2)-1
	testcase=4;
	if((n1=cll_insert_data_after(NULL,1))==NULL || (n2=cll_insert_data_after(n1,2))==NULL || (n3=cll_insert_data_after(n1,3))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after 3 nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(n1->next!=n3 || n3->next!=n2 || n2->next != n1) 
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_insert_data_after order error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_destory(n2)!=3)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}


	//insert 3 nodes (3-1-2)-3
	testcase=5;
	if((n1=cll_insert_data_after(NULL,1))==NULL || (n2=cll_insert_data_after(n1,2))==NULL || (n3=cll_insert_data_before(n1,3))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_before 3 nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(n3->next!=n1 || n1->next!=n2 || n2->next != n3) 
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_insert_data_before order error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_destory(n2)!=3)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}

	//insert 4 nodes (1-2-4-3)-1
	testcase=6;
	if((n1=cll_insert_data_after(NULL,1))==NULL || (n2=cll_insert_data_after(n1,2))==NULL || (n3=cll_insert_data_after(n2,3))==NULL || (n4=cll_insert_data_after(n2,4))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_before 3 nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(n1->next!=n2 || n2->next!=n4 || n4->next != n3 || n3->next != n1) 
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_insert_data_after order error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_destory(n2)!=4)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}

	//remove only 1 node
	testcase=7;
	if((n1=cll_insert_data_after(NULL,1))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after first node failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_remove(n1)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_remove only node failed." << std::endl; 
		return false;
	}

	//remove 1 of 2 nodes
	testcase=8;
	if((n1=cll_insert_data_after(NULL,1))==NULL || (n2=cll_insert_data_after(n1,2))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_remove(n1)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_remove 1 node failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(n2->next!=n2) 
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_remove order error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_destory(n2)!=1)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}

	//remove 1 of 2 nodes
	testcase=9;
	if((n1=cll_insert_data_after(NULL,1))==NULL || (n2=cll_insert_data_after(n1,2))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_remove(n2)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_remove 1 node failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(n1->next!=n1) 
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_remove order error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_destory(n1)!=1)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}


	//remove nodes
	testcase=10;
	if((n1=cll_insert_data_after(NULL,1))==NULL || (n2=cll_insert_data_after(n1,2))==NULL || (n3=cll_insert_data_after(n2,3))==NULL || (n4=cll_insert_data_after(n3,4))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_remove(n2)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_remove 1 node failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_remove(n3)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_remove 1 node failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(n1->next!=n4 || n4->next!=n1) 
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "4: cll_remove order error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_destory(n1)!=2)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "5: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}

	//reverse 1/2/3 nodes list
	testcase=11;
	if((n1=cll_insert_data_after(NULL,1))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_reserve(n1)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_reserve 1 node list failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(n1->next!=n1)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_reserve set next error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if((n2=cll_insert_data_after(n1,2))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "4: cll_insert_data_after node 2 error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_reserve(n1)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "5: cll_reserve 2 nodes list failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(n2->next!=n1 && n1->next!=n2)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "6: cll_reserve set next error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if((n3=cll_insert_data_after(n1,3))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "7: cll_insert_data_after node 3 error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_reserve(n2)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "8: cll_reserve 3 nodes list failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(n1->next!=n2 && n2->next!=n3 || n3->next!=n1)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "9: cll_reserve set next error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_destory(n1)!=3)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "4: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}


	//reverse 5 nodes
	testcase=12;
	if((n1=cll_insert_data_after(NULL,1))==NULL || (n2=cll_insert_data_after(n1,2))==NULL || (n3=cll_insert_data_after(n2,3))==NULL || (n4=cll_insert_data_after(n3,4))==NULL || (n5=cll_insert_data_after(n4,5))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	cll_display(n1);
	if(cll_reserve(n1)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_reserve 5 nodes list failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	cll_display(n5);
	if(n5->next!=n4 && n4->next!=n3 || n3->next!=n2 || n2->next!=n1 || n1->next!=n5)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_reserve set next error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_destory(n1)!=5)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "4: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}

	//cll_is_loop
	testcase=13;
	if((n1=cll_insert_data_after(NULL,1))==NULL || (n2=cll_insert_data_after(n1,2))==NULL || (n3=cll_insert_data_after(n2,3))==NULL || (n4=cll_insert_data_after(n3,4))==NULL || (n5=cll_insert_data_after(n4,5))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_is_loop(n1)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_is_loop error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_is_loop(n2)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_is_loop error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_is_loop(n5)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "4: cll_is_loop error." << std::endl; 
		cll_destory(n1);
		return false;
	}	
	if(cll_break(n2)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "5: cll_break failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_is_loop(n1)==true)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "6: cll_is_loop error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_is_loop(n2)==true)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "7: cll_is_loop error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_is_loop(n5)==true)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "8: cll_is_loop error." << std::endl; 
		cll_destory(n1);
		return false;
	}	

	if(cll_link(n2, n3)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "9: cll_link failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if(cll_is_loop(n5)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "10: cll_is_loop error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	//不重新连接起来,以下销毁的节点数据一定不对!
	if(cll_destory(n1)!=5)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "11: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}

	//cll_is_loop
	testcase=14;
	if((n1=cll_insert_data_after(NULL,1))==NULL || (n2=cll_insert_data_after(n1,2))==NULL || (n3=cll_insert_data_after(n2,3))==NULL || (n4=cll_insert_data_after(n3,4))==NULL || (n5=cll_insert_data_after(n4,5))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after nodes failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	//make a small loop (1->2->3->4->5)  ==>  1->2->(3->4->5)  一对括号表示一个环(head -> tail)
	if(cll_link(n5, n3)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_link failed." << std::endl; 
		cll_destory(n1);
		return false;
	}

	//从任何一个节点(不管环内/环外)都可以测试到环!
	if((loop=cll_find_loop(n1))==NULL)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "4: cll_find_loop error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	if((loop!=n3))
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "5: cll_find_loop error." << std::endl; 
		cll_destory(n1);
		return false;
	}
	//the loop port should be found from outside nodes.
	if(cll_find_loop(n1)!=n3 || cll_find_loop(n2)!=n3)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "6: cll_find_loop error." << std::endl; 
		//cll_destory(n1);
		return false;
	}
	if(cll_is_loop(n1)==false || cll_find_loop(n2)==false || cll_find_loop(n3)==false || cll_find_loop(n4)==false || cll_find_loop(n5)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "7: cll_is_loop error." << std::endl; 
		//cll_destory(n1);
		return false;
	}
	//cll_find_loop from nodes inside the loop.
	std::cout << "cll_find_loop(n3)=" << cll_find_loop(n4)->data << std::endl; 
	std::cout << "cll_find_loop(n4)=" << cll_find_loop(n4)->data << std::endl; 
	std::cout << "cll_find_loop(n5)=" << cll_find_loop(n5)->data << std::endl; 


	//restore
	if(cll_link(n5, n1)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "8: cll_link failed." << std::endl; 
		//cll_destory(n1);
		return false;
	}
	//make a small loop (1->2->3->4->5)  ==>  1->2->3->(4->5)  一对括号表示一个环(head -> tail)
	if(cll_link(n5, n4)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "9: cll_link failed." << std::endl; 
		cll_destory(n1);
		return false;
	}
	//the loop port should be found from outside nodes.
	if(cll_find_loop(n1)!=n4 || cll_find_loop(n2)!=n4 || cll_find_loop(n3)!=n4)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "10: cll_find_loop error." << std::endl; 
		//cll_destory(n1);
		return false;
	}
	//cll_find_loop from nodes inside the loop.
	std::cout << "cll_find_loop(n4)=" << cll_find_loop(n4)->data << std::endl; 
	std::cout << "cll_find_loop(n5)=" << cll_find_loop(n5)->data << std::endl; 

	if(cll_link(n5, n1)==false)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "11: cll_link failed." << std::endl; 
		//cll_destory(n1);
		return false;
	}
	if(cll_destory(n1)!=5)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "12: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}

	//ceate a big listed list.
	testcase=15;
	int N=10000;
	cll_node*n=NULL;
	cll_node**ns=(cll_node**) malloc (sizeof(cll_node*)*N);
	for(int i=0;i<N;i++)
	{
		n=cll_insert_data_after(n,i);		
		ns[i]=n;
	}
	for(int i=0;i<N;i++)
	{
		if(ns[i]->data!=i) 
		{
			std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_insert_data_after error." << std::endl; 
			cll_destory(n1);
			return false;
		}
	}

	int a=1000,b=900;
	for(b=200;b<a;b++)
	{
		int port=a>b?b:a;

		//link a loop
		if(cll_link(ns[a], ns[b])==false)
		{
			std::cout << "CASE" << testcase << " ERROR-" <<  "1: cll_link failed." << std::endl; 
			cll_destory(n1);
			return false;
		}

		//the loop port should be found from outside nodes.
		if(cll_find_loop(ns[100])!=ns[port])
		{
			std::cout << "CASE" << testcase << " ERROR-" <<  "2: cll_find_loop error." << std::endl; 
			//cll_destory(n1);
			return false;
		}

		//restore
		if(cll_link(ns[a], ns[a+1])==false)
		{
			std::cout << "CASE" << testcase << " ERROR-" <<  "3: cll_link failed." << std::endl; 
			cll_destory(n1);
			return false;
		}
	}


	if(cll_destory(n)!=N)
	{
		std::cout << "CASE" << testcase << " ERROR-" <<  "4: cll_destory the count of deleted nodes error." << std::endl; 
		return false;
	}

	std::cout << "TEST ALL " << testcase << " CASES SUCCESSFULLY!!!" << std::endl;
	return true;
}