单链表常见操作——18个难度各异的问题
2012-05-27 21:34
441 查看
一下程序包含了常见了单链表问题,包含18个难度各异的问题,是复习单链表的绝佳资料。
参考资料:
http://cslibrary.stanford.edu/
#include <stdio.h> #include <stdlib.h> #include <assert.h> struct node { int data; struct node *next; }; /* *get the length of a linkedlist */ int Length(struct node *head); /* *new a node, and push into given linkedlist */ void Push(struct node **headRef, int newData); /* *three methods to build list */ struct node* buildListWithTail(int data[], int len); struct node* buildListWithDummy(int data[], int len); struct node* buildListWithLocalRef(int data[], int len); /* *Here are 18 linked list problems arranged in order of difficulty */ /* * Problem id: 1 * *Function name:Count * *Function declare:int Count(struct node *head, int searchFor) * *Function utility:Given a list and an int, return the number of times that int occurs * *Function usage:int count(myList, 2); * *Author:Anonymous * */ int Count(struct node *head, int searchFor); /* * Problem id: 2 * *Function name:GetNth * *Function declare:int GetNth(struct node *head, int index) * *Function utility:Given a list and an index , return the data, in nth node of the list. *The nodes are numbered form 0. Assert fails if the index is invalid(outside 0...length-1). * *Function usage:int lastNode = GetNth(myList, length(myList) - 1); * *Author:Anonymous * */ int GetNth(struct node *head, int index); /* * Problem id: 3 * *Function name:DeleteList * *Function declare:void DeleteList(struct node **headRef) * *Function utility:Deallocates all fo its memory and sets its head pointer to NULL * *Function usage:DeleteList(&myList); * *Author:Anonymous * */ void DeleteList(struct node **headRef); /* * Problem id: 4 * *Function name:Pop() * *Function declare:int Pop(struct node **headRef) * *Function utility:Pop() takes a non-empty list, deletes the head node, and returns the head nodes's data * *Function usage:int a = Pop(&myList); * *Author:Anonymous * */ int Pop(struct node **headRef); /* * Problem id: 5 * *Function name:InsertNth() * *Function declare:void InsertNth(struct node **headRef, int index, int data); * *Function utility:InsertNth can insert a new node at any index within a list. * *Function usage:InsertNth(&head, 0, 13); * *Author:Anonymous * */ void InsertNth(struct node **headRef, int index, int data); /* * Problem id: 6 * *Function name:SortedInsert() * *Function declare:void SortedInsert(struct node **headRef, struct node *newNode) * *Function utility:insert a node into the correct sorted position in a sorted list * *Function usage: * *Author:Anonymous * */ void SortedInsert(struct node **headRef, struct node *newNode); /* * Problem id: 7 * *Function name:InsertSort() * *Function declare:void InsertSort(struct node **headRef) * *Function utility:this function rearranges its nodes so they are sorted in increasing order * *Function usage:InsertSort(&myList); * *Author:Anonymous * */ void InsertSort(struct node **headRef); /* * Problem id: 8 * *Function name:Append() * *Function declare:void Append(struct node** aRef, struct node** bRef) * *Function utility:an Append() function that takes two lists 'a' and 'b', append 'b' onto the end of 'a' and then sets 'b' to NULL * *Function usage:Append(&a, &b); * *Author:Anonymous * */ void Append(struct node** aRef, struct node** bRef); /* * Problem id: 9 * *Function name:FrontBackSplit() * *Function declare:void FrontBackSplit(struct node* source, struct node** fontRef, struct node** backRef) * *Function utility:Given a list, split it into sublists * *Function usage:FrontBackSplit(myList, &a, &b) * *Author:Anonymous * */ void FrontBackSplit(struct node* source, struct node** fontRef, struct node** backRef); /* * Problem id:10 * *Function name:RemoveDuplicates() * *Function declare:void RemoveDuplicates(struct node *head) * *Function utility:it's takes a list sorted in increasing order and deletes *any duplicate nodes from the list * *Function usage:FrontBackSplit(myList) * *Author:Anonymous * */ void RemoveDuplicates(struct node *head); /* * Problem id:11 * *Function name:MoveNode() * *Function declare:void MoveNode(struct node **desRef, struct node **sourceRef) * *Function utility:MoveNode() takes two lists, removes the front node from the second list *and pushed it onto the front of the first * *Function usage:MoveNode(&a, &b) *a={1, 2, 3} *b={2, 3} *After a call to MoveNode(&a, &b) *a={2, 1, 2, 3} *b={3} *Author:Anonymous * */ void MoveNode(struct node **desRef, struct node **sourceRef); /* * Problem id:12 * *Function name:AlternatingSplit() * *Function declare:void AlternatingSplit(struct node *source, struct node**aRef, stuct node** bRef) * *Function utility:function AlternatingSplit that takes on list and divides up its nodes to make two smaller lists. *the sublists should be made from alternating elements in the original list.so if the original list is {a, b, a, b, a}, then one sublist should b *{a, a, a}, and the other should be{b, b} * *Function usage:AlternatingSplit(myList,&a, &b) * *Author:Anonymous * */ void AlternatingSplit(struct node *source, struct node**aRef, struct node** bRef); /* * Problem id:13 * *Function name:ShuffleMerge() * *Function declare:struct node* ShuffleMerge(struct node *a, struct node *b) * *Function utility:Given two lists, merge their nodes together to make one list, *taking nodes alternately between the two lists.So ShuffleMerge() with {1, 2, 3} and {7, 13, 1} should yield {1, 7, 2, 13, 3, 1} * *Function usage: * *Author:Anonymous * */ struct node* ShuffleMerge(struct node *a, struct node *b); /* * Problem id:14 * *Function name:SortedMerge() * *Function declare:struct node * SortedMerge(struct node* a, struct node* b); * *Function utility:takes two lists, each of which is sorted in increasing order, *and merge the two together into one list which is in increasing order * *Function usage: * *Author:Anonymous * */ struct node * SortedMerge(struct node* a, struct node* b); /* * Problem id:15 * *Function name:MergeSort() * *Function declare:void MergeSort(struct node **headRef); * *Function utility:sort a list with merge sort * *Function usage: * *Author:Anonymous * */ void MergeSort(struct node **headRef); /* * Problem id:16 * *Function name:SortedIntersect() * *Function declare:struct node * SortedIntersect(struct node* a, struct node *b); * *Function utility:Given two lists sorted in increasing order, create and *return a new list representing the intersection of the two lists * *Function usage: * *Author:Anonymous * */ struct node * SortedIntersect(struct node* a, struct node *b); /* * Problem id:17 * *Function name:Reverse() * *Function declare:void Reverse(struct node **headRef); * *Function utility:reverse a linked list * *Function usage: Reverse(&myList); * *Author:Anonymous * */ void Reverse(struct node **headRef); /* * Problem id:18 * *Function name:RecursiveReverse() * *Function declare:void RecursiveReverse(struct node ** headRef); * *Function utility:reverse a linked list with a recursive methon * *Function usage:Reverse(&myList); * *Author:Anonymous * */ void RecursiveReverse(struct node ** headRef); int Length(struct node *head) { int count = 0; struct node *current = head; while (current != NULL) { count++; current = current->next; } return count; } void Push(struct node **headRef, int newData) { struct node *newNode; newNode = (struct node *)malloc(sizeof(struct node)); newNode->data = newData; newNode->next =NULL; newNode->next = *headRef; *headRef = newNode; } struct node* buildListWithTail(int data[], int len) { struct node *head = NULL; struct node *tail; int i; Push(&head, data[0]); if( len == 1) { return head; } tail = head; for (i = 1; i < len; i++) { Push(&(tail->next), data[i]); } return head; } struct node* buildListWithDummy(int data[], int len) { struct node dummy; struct node *tail = &dummy; int i; dummy.next = NULL; for (i = 0; i < len; i++) { Push(&(tail->next), data[i]); tail = tail->next; } return dummy.next; } struct node* buildListWithLocalRef(int data[], int len) { } int Count(struct node *head, int searchFor) { struct node * current = head; int count = 0; while (current != NULL) { if (current->data == searchFor) { count++; } current = current->next; } return count; } int GetNth(struct node *head, int index) { struct node* current = head; int count = 0; while (current != NULL) { if (count == index) { return current->data; } count++; current = current->next; } assert(0); } void DeleteList(struct node **headRef) { struct node * current = *headRef; struct node *next; while (current != NULL) { next = current->next; free(current); current = next; } *headRef = NULL; } int Pop(struct node **headRef) { struct node *head; int result; head = *headRef; assert(head != NULL); result = head->data; *headRef = head->next; free(head); return result; } void InsertNth(struct node **headRef, int index, int data) { if (index == 0) { Push(headRef, data); } else { struct node * current = *headRef; int i; for (i = 0; i < index -1; i++) { assert(current != NULL); current = current->next; } assert(current != NULL); Push(&(current->next), data); } } void SortedInsert(struct node **headRef, struct node *newNode) { if (*headRef == NULL || (*headRef)->data >= newNode->data) { newNode->next = *headRef; *headRef = newNode; } else { struct node * current = *headRef; while (current->next != NULL && current->next->data < newNode->data) { current = current->next; } newNode->next = current->next; current->next = newNode; } } void InsertSort(struct node **headRef) { struct node * result = NULL; struct node *current = *headRef; struct node * next; while (current != NULL) { next = current->next; SortedInsert(&result, current); current = next; } *headRef = result; } void Append(struct node** aRef, struct node** bRef) { struct node *current; if (*aRef == NULL) { *aRef = *bRef; } else { current = *aRef; while (current->next != NULL) { current = current->next; } current->next = *bRef; } *bRef = NULL; } void FrontBackSplit(struct node* source, struct node** fontRef, struct node** backRef) { struct node *fast; struct node *slow; if (source == NULL || source->next == NULL) { *fontRef = source; *backRef = NULL; } else { slow = source; fast = source->next; while (fast != NULL) { fast = fast->next; if (fast != NULL) { slow = slow->next; fast = fast->next; } } *fontRef = source; *backRef = slow->next; slow->next = NULL; } } void RemoveDuplicates(struct node *head) { struct node *current = head; if (current == NULL) { return; } while (current->next != NULL) { if (current->data == current->next->data) { struct node* nextNext = current->next->next; free(current->next); current->next = nextNext; } else { current = current->next; } } } void MoveNode(struct node **desRef, struct node **sourceRef) { struct node *newNode = *sourceRef; assert(newNode != NULL); *sourceRef = newNode->next; newNode->next = *desRef; *desRef = newNode; } void AlternatingSplit(struct node *source, struct node**aRef, struct node** bRef) { struct node *a = NULL; struct node *b = NULL; struct node *current = source; while (current != NULL) { MoveNode(&a, ¤t); if (current != NULL) { MoveNode(&b, ¤t); } } *aRef = a; *bRef = b; } struct node* ShuffleMerge(struct node *a, struct node *b) { struct node dummy; struct node * tail = &dummy; dummy.next = NULL; while (1) { if (a == NULL) { tail->next = b; break; } else if (b == NULL) { tail->next = a; break; } else { tail->next = a; tail = a; a = a->next; tail->next = b; tail = b; b = b->next; } } return (dummy.next); } struct node * shuffleMerge2(struct node *a, struct node *b) { struct node *result; struct node *recur; if (a == NULL) { return a; } else if (b == NULL) { return b; } else { recur = shuffleMerge2(a->next, b->next); result = a; a->next = b; b->next = recur; } return result; } struct node * SortedMerge(struct node* a, struct node* b) { struct node dummy; struct node *tail = &dummy; dummy.next = NULL; while (1) { if (a == NULL) { tail->next = b; break; } else if (b == NULL) { tail->next = a; break; } if (a->data <= b->data) { MoveNode(&(tail->next), &a); } else { MoveNode(&(tail->next), &b); } tail = tail->next; } return dummy.next; } void MergeSort(struct node **headRef) { struct node *head = *headRef; struct node *a; struct node *b; if ((head == NULL) || (head->next == NULL)) { return; } FrontBackSplit(head, &a, &b); MergeSort(&a); MergeSort(&b); *headRef = SortedMerge(a, b); } struct node * SortedIntersect(struct node* a, struct node *b) { struct node dummy; struct node* tail = &dummy; dummy.next = NULL; while (a != NULL && b != NULL) { if (a->data == b->data) { Push(&(tail->next), a->data); tail = tail->next; a = a->next; b = b->next; } else if (a->data < b->data) { a = a->next; } else { b = b->next; } } return (dummy.next); } void Reverse(struct node **headRef) { struct node *result = NULL; struct node *current = *headRef; struct node *next; while (current != NULL) { next = current->next; current->next = result; result = current; current = next; } *headRef = result; } void Reverse2(struct node **headRef) { struct node *result = NULL; struct node *current = *headRef; while (current != NULL) { MoveNode(&result, ¤t); } *headRef = result; } void RecursiveReverse(struct node ** headRef) { struct node *first; struct node *rest; if (*headRef == NULL) { return; } first = *headRef; rest = first->next; if (rest == NULL) { return; } RecursiveReverse(&rest); first->next->next = first; first->next = NULL; *headRef = rest; } void print(struct node *head) { struct node *current = head; while (current != NULL) { printf("%d\t", current->data); current = current->next; } printf("\n"); } int main(int argc, const char *argv[]) { int data[] = {1, 8, 5, 4, 9}; int i; struct node *head = buildListWithDummy(data, sizeof(data)/sizeof(int)); print(head); Reverse( &head); print(head); InsertNth( &head, 1, -1); print(head); InsertSort(&head); print(head); printf("the length of list is %d\n", Length(head)); i = Pop(&head); Push(&head, 3); Push(&head, 3); Push(&head, 3); Push(&head, 3); printf("the length of list is %d\n", Length(head)); print(head); printf("the count of 3 is %d\n", Count(head, 3)); MergeSort(&head); print(head); RemoveDuplicates(head); print(head); return 0; }
参考资料:
http://cslibrary.stanford.edu/
相关文章推荐
- 单链表基本操作以及一些常见的面试问题
- python操作mysql方法和常见问题
- 树莓派操作目录以及常用命令整理——树莓派入手常见问题(四)
- JS哪些操作带来reflow?常见问题优化
- C语言链表常见基本操作
- 数据结构之链表与数组(二) -单向链表上的简单操作问题
- HIVE操作常见问题汇总
- Linux下常见操作问题及解决方案两例
- 面试中常见链表问题1:合并两个有序链表
- sql service2000的安装 操作 常见问题
- 常见链表操作之链表合并
- 笔记本出厂预装Win8改装Win7的操作步骤及常见问题___联想e430c之类可供参考
- Linux shell常见命令操作以及问题解决
- 链表常见的问题【转】
- 链表常见面试题一:基本问题
- 数据结构之链表与数组(二) -单向链表上的简单操作问题
- 常见的链表操作
- 链表的常见操作
- 链表的常见操作