int main(int argc, char* argv[]) { s_node *list, *dup; s_node linkedlist, one, two, three, four; // Creating a test LinkedList init_node(&linkedlist, 0); init_node(&one, 1); init_node(&two, 2); init_node(&three, 3); init_node(&four, 4); linkedlist.next = &one; one.next = &two; two.next = &three; three.next = &four; list = &linkedlist; dup = duplicate_list(list); printf("%s\n", "Original linkedlist and Address."); print_list(list); printf("%s\n", "Duplicate linkedlist and Address."); print_list(dup); return 0; }
RandomListNode *copyRandomList(RandomListNode *head) { // write your code here if(!head) return NULL; head = duplicate_list(head); head = set_random_pointers(head); head = separate_deep_copy_list(head); return head; }
int test_compare(void) { shList il1; shList sl1; bool good = true; sh_list_init(&il1, _intptrcpy, sizeof(int *), ipcmp); sh_list_init(&sl1, _charptrcpy, sizeof(char *), scmp); if (sh_list_compare(&il, &il) != 0 || sh_list_compare(&sl, &sl) != 0 || sh_list_compare_lexic(&il, &il) != 0 || sh_list_compare_lexic(&sl, &sl) != 0) goto exit_bad_equal; duplicate_list(&il1, &il, &sl1, &sl); if (sh_list_append(&il1, &idata[0]) || sh_list_append(&sl1, sdata[0])) goto exit_no_mem; if (sh_list_compare(&il, &il1) == 0 || sh_list_compare(&sl, &sl1) == 0) goto exit_bad_inequal; if (sh_list_compare_lexic(&il, &il1) != -1 || sh_list_compare_lexic(&il1, &il) != 1 || sh_list_compare_lexic(&sl, &sl1) != -1 || sh_list_compare_lexic(&sl1, &sl) != 1) goto exit_bad_lexic; goto exit_cleanup; exit_no_mem: fprintf(stderr, "compare: out of memory\n"); goto exit_fail; exit_bad_equal: fprintf(stderr, "compare: failed to recognize equal lists\n"); goto exit_fail; exit_bad_inequal: fprintf(stderr, "compare: failed to recognize inequal lists\n"); goto exit_fail; exit_bad_lexic: fprintf(stderr, "compare: incorrect lexicographical comparison\n"); goto exit_fail; exit_fail: dump_data(DUMP_FILE); good = false; exit_cleanup: sh_list_free(&il1); sh_list_free(&sl1); return good?0:-1; }
int test_concat(void) { shList il1, il2, il3, il4; shList sl1, sl2, sl3, sl4; shList itemp, stemp; int ret; size_t i; int *ext_idata = NULL; size_t ext_idata_count; char **ext_sdata = NULL; size_t ext_sdata_count; bool good = true; sh_list_init(&il1, _intptrcpy, sizeof(int *)); sh_list_init(&il2, _intptrcpy, sizeof(int *)); sh_list_init(&il3, _intptrcpy, sizeof(int *)); sh_list_init(&il4, _intptrcpy, sizeof(int *)); sh_list_init(&sl1, _charptrcpy, sizeof(char *)); sh_list_init(&sl2, _charptrcpy, sizeof(char *)); sh_list_init(&sl3, _charptrcpy, sizeof(char *)); sh_list_init(&sl4, _charptrcpy, sizeof(char *)); sh_list_init(&itemp, _intptrcpy, sizeof(int *)); sh_list_init(&stemp, _charptrcpy, sizeof(char *)); /* {} + {} */ ret = concat_and_test(&il1, &il2, &sl1, &sl2, NULL, 0, NULL, 0); if (ret == -1) goto exit_test_fail_both_empty; /* l + {} */ ret = concat_and_test(&il, &il1, &sl, &sl1, idata, idata_count, sdata, sdata_count); if (ret == -1) goto exit_test_fail_empty_right; /* {} + l */ ret = concat_and_test(&il2, &il, &sl2, &sl, idata, idata_count, sdata, sdata_count); if (ret == -1) goto exit_test_fail_empty_left; sh_list_concat(&il, &il2); sh_list_concat(&sl, &sl2); /* l + l/2 */ ext_idata_count = idata_count / 2; ext_sdata_count = sdata_count / 2; ext_idata = malloc((idata_count + ext_idata_count) * sizeof *ext_idata); ext_sdata = malloc((sdata_count + ext_sdata_count) * sizeof *ext_sdata); if (ext_idata == NULL || ext_sdata == NULL) goto exit_no_mem; memcpy(ext_idata, idata, idata_count * sizeof *idata); memcpy(ext_sdata, sdata, sdata_count * sizeof *sdata); for (i = 0; i < ext_idata_count; ++i) { ext_idata[i + idata_count] = idata[i]; sh_list_append(&il3, &idata[i]); } for (i = 0; i < ext_sdata_count; ++i) { ext_sdata[i + sdata_count] = sdata[i]; sh_list_append(&sl3, sdata[i]); } duplicate_list(&itemp, &il, &stemp, &sl); ret = concat_and_test(&itemp, &il3, &stemp, &sl3, ext_idata, idata_count + ext_idata_count, ext_sdata, sdata_count + ext_sdata_count); if (ret == -1) goto exit_test_fail_smaller_right; /* l/2 + l */ memcpy(ext_idata + ext_idata_count, idata, idata_count * sizeof *idata); memcpy(ext_sdata + ext_sdata_count, sdata, sdata_count * sizeof *sdata); for (i = 0; i < ext_idata_count; ++i) { ext_idata[i] = idata[i]; sh_list_append(&il4, &idata[i]); } for (i = 0; i < ext_sdata_count; ++i) { ext_sdata[i] = sdata[i]; sh_list_append(&sl4, sdata[i]); } duplicate_list(&itemp, &il, &stemp, &sl); ret = concat_and_test(&il4, &itemp, &sl4, &stemp, ext_idata, idata_count + ext_idata_count, ext_sdata, sdata_count + ext_sdata_count); if (ret == -1) goto exit_test_fail_smaller_left; /* l/2 + l/2 */ memcpy(ext_idata + ext_idata_count, ext_idata, ext_idata_count * sizeof *ext_idata); memcpy(ext_sdata + ext_sdata_count, ext_sdata, ext_sdata_count * sizeof *ext_sdata); for (i = 0; i < ext_idata_count; ++i) sh_list_append(&il3, &idata[i]); for (i = 0; i < ext_sdata_count; ++i) sh_list_append(&sl3, sdata[i]); duplicate_list(&itemp, &il3, &stemp, &sl3); ret = concat_and_test(&il3, &itemp, &sl3, &stemp, ext_idata, ext_idata_count * 2, ext_sdata, ext_sdata_count * 2); if (ret == -1) goto exit_test_fail_equal_size; if (!sh_list_concat(&il3, &il3) || !sh_list_concat(&sl3, &sl3)) goto exit_accepted_duplicate; good = true; goto exit_cleanup; exit_no_mem: fprintf(stderr, "concat: out of memory\n"); goto exit_fail; exit_test_fail_empty_right: fprintf(stderr, "concat: bad concatenation with empty list on the right\n"); goto exit_fail; exit_test_fail_empty_left: fprintf(stderr, "concat: bad concatenation with empty list on the left\n"); goto exit_fail; exit_test_fail_smaller_right: fprintf(stderr, "concat: bad concatenation with smaller list on the right\n"); goto exit_fail; exit_test_fail_smaller_left: fprintf(stderr, "concat: bad concatenation with smaller list on the left\n"); goto exit_fail; exit_test_fail_both_empty: fprintf(stderr, "concat: bad concatenation with two empty lists\n"); goto exit_fail; exit_test_fail_equal_size: fprintf(stderr, "concat: bad concatenation with lists of same size\n"); goto exit_fail; exit_accepted_duplicate: fprintf(stderr, "concat: accepted concatenation with itself (causes loop)\n"); exit_fail: dump_data(DUMP_FILE); good = false; exit_cleanup: sh_list_free(&il1); sh_list_free(&il2); sh_list_free(&il3); sh_list_free(&il4); sh_list_free(&sl1); sh_list_free(&sl2); sh_list_free(&sl3); sh_list_free(&sl4); sh_list_free(&itemp); sh_list_free(&stemp); free(ext_idata); free(ext_sdata); return good?0:-1; }
static SEXP duplicate1(SEXP s, Rboolean deep) { SEXP t; R_xlen_t i, n; duplicate1_elts++; duplicate_elts++; switch (TYPEOF(s)) { case NILSXP: case SYMSXP: case ENVSXP: case SPECIALSXP: case BUILTINSXP: case EXTPTRSXP: case BCODESXP: case WEAKREFSXP: return s; case CLOSXP: PROTECT(s); PROTECT(t = allocSExp(CLOSXP)); SET_FORMALS(t, FORMALS(s)); SET_BODY(t, BODY(s)); SET_CLOENV(t, CLOENV(s)); DUPLICATE_ATTRIB(t, s, deep); if (NOJIT(s)) SET_NOJIT(t); if (MAYBEJIT(s)) SET_MAYBEJIT(t); UNPROTECT(2); break; case LISTSXP: PROTECT(s); t = duplicate_list(s, deep); UNPROTECT(1); break; case LANGSXP: PROTECT(s); PROTECT(t = duplicate_list(s, deep)); SET_TYPEOF(t, LANGSXP); DUPLICATE_ATTRIB(t, s, deep); UNPROTECT(2); break; case DOTSXP: PROTECT(s); PROTECT(t = duplicate_list(s, deep)); SET_TYPEOF(t, DOTSXP); DUPLICATE_ATTRIB(t, s, deep); UNPROTECT(2); break; case CHARSXP: return s; break; case EXPRSXP: case VECSXP: n = XLENGTH(s); PROTECT(s); PROTECT(t = allocVector(TYPEOF(s), n)); for(i = 0 ; i < n ; i++) SET_VECTOR_ELT(t, i, duplicate_child(VECTOR_ELT(s, i), deep)); DUPLICATE_ATTRIB(t, s, deep); COPY_TRUELENGTH(t, s); UNPROTECT(2); break; case LGLSXP: DUPLICATE_ATOMIC_VECTOR(int, LOGICAL, t, s, deep); break; case INTSXP: DUPLICATE_ATOMIC_VECTOR(int, INTEGER, t, s, deep); break; case REALSXP: DUPLICATE_ATOMIC_VECTOR(double, REAL, t, s, deep); break; case CPLXSXP: DUPLICATE_ATOMIC_VECTOR(Rcomplex, COMPLEX, t, s, deep); break; case RAWSXP: DUPLICATE_ATOMIC_VECTOR(Rbyte, RAW, t, s, deep); break; case STRSXP: /* direct copying and bypassing the write barrier is OK since t was just allocated and so it cannot be older than any of the elements in s. LT */ DUPLICATE_ATOMIC_VECTOR(SEXP, STRING_PTR, t, s, deep); break; case PROMSXP: return s; break; case S4SXP: PROTECT(s); PROTECT(t = allocS4Object()); DUPLICATE_ATTRIB(t, s, deep); UNPROTECT(2); break; default: UNIMPLEMENTED_TYPE("duplicate", s); t = s;/* for -Wall */ } if(TYPEOF(t) == TYPEOF(s) ) { /* surely it only makes sense in this case*/ SET_OBJECT(t, OBJECT(s)); (IS_S4_OBJECT(s) ? SET_S4_OBJECT(t) : UNSET_S4_OBJECT(t)); } return t; }
bool test_duplicate_list(int node_count, bool use_q_n_d) { srand(static_cast<unsigned int>(time(NULL))); int NUM_NODES = node_count; //first create the list... s_node* head = new s_node(); head->next = NULL; head->reference = NULL; s_node* tmp = head; std::vector<s_node*> nodes; nodes.push_back(head); //create a list of NUM_NODES... for(int i = 0; i < NUM_NODES; i++) { tmp->next = new s_node(); tmp->reference = NULL; tmp = tmp->next; nodes.push_back(tmp); } //do random idexes.. int count = rand() %NUM_NODES + 1; for(int i = 0; i < count; ++i) { int index = rand() % NUM_NODES; int ref_index = rand() % NUM_NODES; nodes[index]->reference = nodes[ref_index]; } s_node* dupe_list; unsigned int start = clock(); if(use_q_n_d) { dupe_list = duplicate_list_quick_and_dirty(head); } else { dupe_list = duplicate_list(head); } std::cout << "Runtime: " << clock()-start << " msec" << std::endl; bool to_return = true; if(dupe_list == NULL) { to_return = false; } s_node* head_ptr = head; s_node* dupe_ptr = dupe_list; //verify that the two lists are identical std::hash_map<s_node*,int> map1; std::hash_map<s_node*,int> map2; int id = 0; // first create id's for each node while(head_ptr != NULL) { map1[head_ptr] = ++id; map2[dupe_ptr] = id; dupe_ptr = dupe_ptr->next; head_ptr = head_ptr->next; } head_ptr = head; dupe_ptr = dupe_list; // now ensure the reference nodes have the same id // which they will if the ndoes were created in the same order // and the references point to the proper nodes while(head_ptr != NULL) { if(head_ptr->reference != NULL) { int head_id = (*map1.find(head_ptr->reference)).second; int dupe_id = (*map2.find(dupe_ptr->reference)).second; if(head_id != dupe_id) { to_return = false; break; } } head_ptr = head_ptr->next; dupe_ptr = dupe_ptr->next; } for (std::vector<s_node*>::iterator it = nodes.begin(); it!=nodes.end(); ++it) { delete *it; *it = NULL; } s_node* temp = dupe_list; while(temp != NULL) { s_node* temp2 = temp; temp = temp2->next; delete temp2; temp2 = NULL; } return to_return; }