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; }