您的位置:首页 > 其它

单链表常见操作——18个难度各异的问题

2012-05-27 21:34 441 查看
一下程序包含了常见了单链表问题,包含18个难度各异的问题,是复习单链表的绝佳资料。

#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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: