算法导论--第十章:基本数据结构

10.1 栈和队列

栈的实现:

#include <stdio.h>
#include <limits.h>

#define SIZE 128
int Stack[ SIZE ];
int top = -1;

int stack_empty( int Stack[] )
{
	if ( -1 == top ){
		return 1;
	}
	return 0;
}

int stack_full( int Stack[] )
{
	if ( SIZE - 1 == top ){
		return 1;
	}
	return 0;
}

void push( int Stack[], int value )
{
	if ( stack_full( Stack ) ){
		printf("\nerror: stack full\n");
		return;
	}
	top += 1;
	Stack[ top ] = value;
}

int pop( int Stack[] )
{
	if ( stack_empty( Stack ) ){
		printf("\nerror: stack empty\n");
		return INT_MIN;
	}
	return Stack[ top-- ];
}

int main( void )
{
	int i = 0;
	for ( i = 0; i < 10; i++ ){
		push( Stack, i * i );
	}
	for ( i = 0; i < 11; i++ ){
		printf("%d ", pop( Stack ) );
	}

	return 0;
}
程序输出:

队列的实现:

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

#define SIZE 10
int Queue[ SIZE ];
int top = 0;
int tail = 0;

int queue_empty( int Queue[] )
{
	if ( top == tail ){
		top = tail = 0;		//对空的队列进行初始化
		return 1;
	}

	return 0;
}

int queue_full( int Queue[] )
{
	if ( ( tail + 1 ) % SIZE  == top ){		//实际上队列的最后一个元素为空,用来判断 empty和 full的情况
		return 1;
	}

	return 0;
}

void push( int Queue[], int value )
{
	if ( queue_full( Queue ) ){
		printf("\nerror: queue full\n");
		return;
	}
	Queue[ tail++ ] = value;
}

int pop( int Queue[] )
{
	if ( queue_empty( Queue ) ){
		printf("\nerror:queue emtpy, the value to be: ");
		return INT_MIN;
	}
	return Queue[ top++ ];
}

int main( void )
{
	int i = 0;
	for ( i = 0; i < 10; i++ ){
		push( Queue, i * i );
	}
	for ( i = 0; i < 10; i++ ){
		printf("%d ", pop( Queue ) );
	}
	printf( "\n" );

	return 0;
}

程序输出:

学好C语言后,你才会明白为什么C++更好,即使它有许多的坑.

习题10.1-2:一个数组,两个堆栈

#include <stdio.h>
#include <limits.h>

#define SIZE 10
int Stack[ SIZE ];
int top1 = 0;
int top2 = SIZE - 1;

int stack_full( int Stack[] )
{
	if ( top1 - 1 == top2 ){
		return 1;
	}

	return 0;
}

void push( int Stack[], int style, int value )
{
	if ( stack_full( Stack ) ){
		printf("error:stack full\n");
		return;
	}
	if ( !style ){
		Stack[ top1++ ] = value;
	}
	else{
		Stack[ top2-- ] = value;
	}
}

int pop( int Stack[], int style )
{
	if ( !style ){
		if ( !top1 ){
			printf("error:first stack is empty\n");
			return INT_MIN;
		}
		return Stack[ --top1 ];
	}
	else{
		if ( top2 == SIZE - 1 ){
			printf("error: second stack is empty\n");
			return INT_MIN;
		}
		return Stack[ ++top2 ];
	}
}

int main( void )
{
	int i = 0;
	int tempValue;
	for ( i = 0; i < 5; i++ ){
		push( Stack, 0, i * i );
	}
	for ( i = 6; i > 0; i-- ){
		push( Stack, 1, i * i );
	}
	for ( i = 0; i < 10; i++ ){
		tempValue = pop( Stack, 0 );
		if ( tempValue == INT_MIN ){
			break;
		}
		printf("%d ", tempValue );
	}
	printf("\n");
	for ( i = 0; i < 10; i++ ){
		tempValue = pop( Stack, 1 );
		if ( tempValue == INT_MIN ){
			break;
		}
		printf("%d ", tempValue );
	}
	printf("\n");

	return 0;
}
程序输出:

习题10.1-5:双端队列

#include <stdio.h>
#include <limits.h>

#define SIZE 10
int Double_queue[ SIZE ];
int top1 = 0;
int tail1 = 0;
int top2 = SIZE - 1;
int tail2 = SIZE - 1;

int empty_double_queue( int Double_queue[] )
{
	if ( top1 == tail1 && top2 == tail2 ){
		top1 = tail1 = 0;
		top2 = tail2 = SIZE - 1;
		return 1;
	}

	return 0;
}

int full_double_queue( int Double_queue[] )
{
 	if ( tail1 == ( tail2 - 1 ) % SIZE && ( top2 + 1 ) % SIZE == top1 ){	//对于双端队列,需要提供两个空元素用于判断是否为空
 		return 1;
 	}

	return 0;
}

void push_front( int Double_queue[], int value )
{
	if ( full_double_queue( Double_queue ) ){
		printf("error: double queue full\n");
		return;
	}

	Double_queue[ tail1 ] = value;
	tail1 = ( tail1 + 1 ) % SIZE;
}

int pop_front( int Double_queue[] )
{
	if ( empty_double_queue( Double_queue ) ){
		printf("\nerror: double queue empty");
		return INT_MIN;
	}

	if ( top1 != tail1 ){
		if ( SIZE - 1 == top1 ){
			top1 = 0;
			return Double_queue[ SIZE - 1 ];
		}
		return Double_queue[ top1++ ];
	}
	else{
		if ( SIZE - 1 == tail2 ){
			tail2 = 0;
			return Double_queue[ tail2++ ];
		}
		return Double_queue[ ++tail2 ];
	}
}

void push_tail( int Double_queue[], int value )
{
	if ( full_double_queue( Double_queue ) ){
		printf("\nerror: double queue full\n");
		return;
	}

	Double_queue[ tail2 ] = value;
	tail2 = ( 0 == tail2 ) ? SIZE - 1 : tail2 - 1;
}

int pop_tail( int Double_queue[] )
{
	if ( empty_double_queue( Double_queue ) ){
		printf("error: double queue empty\n");
		return INT_MIN;
	}
	if ( top2 != tail2 ){
		if ( 0 == top2 ){
			top2 = SIZE - 1;
			return Double_queue[ 0 ];
		}
		return Double_queue[ top2-- ];
	}
	else{
		if ( tail1 == 0 ){
			tail1 = SIZE - 1;
			return Double_queue[ tail1-- ];
		}
		return Double_queue[ --tail1 ];
	}
}

int main( void )
{
	int i = 0;
	for ( i = 0; i < 5; i++ ){
		push_front( Double_queue, i * i );
	}
	for ( i = 0; i < 6; i++ ){
		push_tail( Double_queue, i * i );
	}
	for ( i = 0; i < 11; i++ ){
		printf("%d ", pop_front( Double_queue ) );
	}

	for ( i = 0; i < 5; i++ ){
		push_front( Double_queue, i * i );
	}
	for ( i = 0; i < 6; i++ ){
		push_tail( Double_queue, i * i );
	}
	for ( i = 0; i < 11; i++ ){
		printf("%d ", pop_tail( Double_queue ) );
	}

	return 0;
}
程序输出:

习题10.1-6:两个栈实现一个队列

这里的队列环回通过当堆栈为空时候进行初始化来实现:

#include <stdio.h>
#include <limits.h>

#define SIZE 10
int Stack_push[ SIZE ];
int Stack_pop[ SIZE ];
int top1 = -1;
int top2 = SIZE;

int empty_queue( void )
{
	if ( top1 + top2 == SIZE - 1 ){
		top1 = -1;
		top2 = SIZE;
		return 1;
	}

	return 0;
}

int full_queue( void )
{
	if ( top1 == top2 - 1 ){
		return 1;
	}

	return 0;
}

void push( int value )
{
	if ( full_queue() ){
		printf("\nerror:queue full\n");
		return;
	}
	top1++;
	Stack_push[ top1 ] = value;
	Stack_pop[ SIZE - 1 - top1 ] = value;
}

int pop( void )
{
	if ( empty_queue() ){
		printf("\nerror: queue empty\n");
		return INT_MIN;
	}
	top2--;
	return Stack_push[ top2 ];
}

int main( void )
{
	int i = 0;

	for ( i = 0; i < 11; i++ ){
		push( i * i );
	}

	for ( i = 0; i < 11; i++ ){
		printf("%d ", pop() );
	}
	printf("\n");

	for ( i = 0; i < 11; i++ ){
		push( i * i );
	}

	for ( i = 0; i < 11; i++ ){
		printf("%d ", pop() );
	}
	return 0;
}
程序输出:

习题10.1-7:两个队列实现一个栈

#include <stdio.h>
#include <limits.h>

#define SIZE 10
int queue_push[ SIZE ];
int queue_pop[ SIZE ];
int top1 = 0;
int tail1 = 0;
int top2 = SIZE - 1;
int tail2 = SIZE - 1;

//queue_push做环回,而queue_pop只是做简单的出栈操作
int stack_empty( void )
{
	if ( tail2 == top2 ){
		top1 = tail1 = 0;
		top2 = tail2 = SIZE - 1;
		return 1;
	}

	return 0;
}

int stack_full( void )
{
	if ( 0 == tail2 ){
		printf("\nerror: stack full\n");
		return 1;
	}

	return 0;
}

void push( int value )
{
	if ( stack_full() ){
		printf("\nerror: stack full\n");
		return;
	}
	queue_push[ tail1 ] = value;
	queue_pop[ tail2 ] = value;
	tail1 = ( tail1 == SIZE - 1 ) ? 0 : tail1 + 1;
	tail2 = ( tail2 == 0 ) ? SIZE - 1 : tail2 - 1;
}

int pop()
{
	if ( stack_empty() ){
		printf("\nerror: stack empty\n");
		return INT_MIN;
	}
	if ( SIZE - 1 == tail2 ){
		tail2 = 0;
		return queue_pop[ --tail2 ];
	}
	return queue_pop[ ++tail2 ];
}

int main( void )
{
	int i = 0;
	for ( i = 0; i < 11; i++ ){
		push( i * i );
	}
	for ( i = 0; i < 5; i++ ){
		printf("%d ", pop() );
	}
	printf("\n");
	for ( i = 0; i < 10; i++ ){
		push( i * i );
	}
	for ( i = 0; i < 10; i++ ){
		printf("%d ", pop() );
	}

	return 0;
}
程序输出:

10.2 链表

双向链表的实现

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct NODE{
	struct NODE *prev;
	struct NODE *next;
	int			data;
} Node;

void insert_node( Node *node, int value )
{
	if ( node->next == node && node->prev == node ){			//链表为空时
		Node *newnode = ( Node * )malloc( sizeof( Node * ) );
		newnode->next = node;
		newnode->prev = node;
		node->prev = newnode;
		node->next = newnode;
		newnode->data = value;
	}
	else{
		Node *newnode = ( Node * )malloc( sizeof( Node * ) );
		while ( ( INT_MIN != node->next->data ) && ( node->data < value ) ){
			node = node->next;
		}
		if ( INT_MIN == node->next->data && node->data < value ){	//插到链表末尾
			newnode->next = node->next;
			newnode->prev = node;
			newnode->data = value;
			node->next->prev = newnode;
			node->next = newnode;
		}
		else{
			newnode->next = node;					//插入到链表中间
			newnode->prev = node->prev;
			newnode->data = value;
			node->prev->next = newnode;
			node->prev = newnode;
		}
	}
}

void delete_node( Node *node, int value )
{
	node = node->next;
	while ( INT_MIN != node->data && node->data < value ){
		node = node->next;
	}
	if ( INT_MIN == node->data || node->data > value ){
		printf("we do not find it\n");
		return;
	}
	else{
		node->prev->next = node->next;
		node->next->prev = node->prev;
	}
}

void print_list( Node *node )
{
	node = node->next;	
	while ( INT_MIN != node->data ){
		printf("%d->", node->data );
		node = node->next;
	}
	printf("NULL\n");
}

int main( void )
{
	int i = 0;
	Node *node = ( Node * )malloc( sizeof( Node * ) );
	node->prev = node;
	node->next = node;
	node->data = INT_MIN;			//只能通过data来标识NIL节点和判断是否到达尾节点
	for ( i = 1; i < 10; i += 2 ){
		insert_node( node, i );
	}
	for ( i = 0; i < 10; i += 2 ){
		insert_node( node, i );
	}
	print_list( node );

	for ( i = 0; i < 10; i += 3 ){
		delete_node( node, i );
	}
	print_list( node );

	return 0;
}
这是调试时候显示的结果,是正确的:

但是,直接运行的结果却是:

我只能表示无奈,因为调试正确,直接运行错误,我无法进行错误的查找.

但这种写法有个好处是:头节点已经在主函数中确定,所以在插入函数中,不必把指针传递进去修改链表(看下列代码):

最后向一位师兄请教后才发现问题所在:

Node *node = ( Node * )malloc( sizeof( Node * ) );
是错误的,我们不能分配一个指针大小的空间!!!!!!正确应该写为:
Node *node = ( Node * )malloc( sizeof( Node ) );
用正确的写法后,程序正常的输出.

尝试用正常的思维,不用哨兵来完成双向链表:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct NODE{
	struct NODE *prev;
	struct NODE *next;
	int			data;
} Node;

void insert_node( Node **node, int value )
{
	Node **root = node;
	if ( NULL == *root ){
		Node *newnode = ( Node * )malloc( sizeof( Node * ) );
		newnode->prev = NULL;
		newnode->next = NULL;
		newnode->data = value;
		*root = newnode;
	}
	else{
		Node *newnode = ( Node * )malloc( sizeof( Node * ) );
		while ( NULL != ( *root )->next && ( *root )->data < value ){
			*root = ( *root )->next;
		}
		if ( NULL == ( *root )->next && ( *root )->data < value ){
			newnode->next = NULL;
			newnode->prev = ( *root );
			newnode->data = value;
			( *root )->next = newnode;
		}
		else{
			newnode->next = ( *root );
			newnode->prev = ( *root )->prev;
			newnode->data = value;
			( *root )->prev->next = newnode;
			( *root )->prev = newnode;
		}
	}
}

void print_list( Node *node )
{
	if ( NULL != node ){
		print_list( node->prev );
		printf("%d->", node->data );
	}
}

int main( void )
{
	int i = 0;
	Node *node = ( Node * )malloc( sizeof( Node * ) );
	node = NULL;

	for ( i = 0; i < 10; i++ ){
		insert_node( &node, i );
	}

	print_list( node->next );
	printf("NULL\n");

	return 0;
}
程序输出:

但是运行还是直接出错..而且这里还有一个很严重的问题:如果将node重新指向头节点???

这里只需要将malloc( sizeof( Node * ) )改为malloc( sizeof( Node ) )即可.

是不是一定要一个哨兵的存在,来实现双向链表???

习题10.2-2:堆栈的实现:

#include <stdio.h>
#include <stdlib.h>

typedef struct NODE{
	struct NODE *next;
	int			data;
} Node;

void push( Node **node, int value )
{
	Node *newnode = ( Node * )malloc( sizeof( Node * ) );
	newnode->next = NULL;
	newnode->data = value;
	newnode->next = *node;
	*node = newnode;
}

int pop( Node **node )
{
	int result;
	if ( NULL == *node ){
		printf("error:stack is empty\n");
		return INT_MIN;
	}
	result = ( *node )->data;
	*node = ( *node )->next;

	return result;
}

int main( void )
{
	int i = 0;
	Node *node = ( Node * )malloc( sizeof( Node * ) );
	node = NULL;

	for ( i = 0; i < 10; i++ ){
		push( &node, i );
	}

	for ( i = 0; i < 5; i++ ){
		printf("%d ", pop( &node ) );
	}
	printf("\n");

	for ( i = 10; i < 15; i++ ){
		push( &node, i );
	}

	for ( i = 0; i < 10; i++ ){
		printf("%d ", pop( &node ) );
	}


	return 0;
}
程序输出:

10.2-3:队列的实现

还是吸取教训,用一个哨兵当作头节点,而且通过传值来达到不改变node的方法:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct NODE{
	struct NODE *next;
	int			data;
} Node;

void push( Node *node, int value )
{
	Node *newnode = ( Node * )malloc( sizeof( Node ) );
	newnode->next = NULL;
	newnode->data = value;
	if ( NULL == node->next ){
		node->next = newnode;
	}
	else{
		while ( NULL != node->next ){
			node = node->next;
		}
		node->next = newnode;
	}
}

int pop( Node *node )
{
	Node *tempNode;
	int result;
	if ( NULL == node->next ){
		printf("\nerror: queue empty");
		return INT_MIN;
	}
	tempNode = node->next;
	result = node->next->data;
	node->next = node->next->next;
	free( tempNode );
	tempNode = NULL;

	return result;
}

int main( void )
{
	int i = 0;
	Node *node = ( Node * )malloc( sizeof( Node ) );
	node->next = NULL;
	node->data = INT_MIN;

	for ( i = 0; i < 5; i++ ){
		push( node, i );
	}
	for ( i = 0; i < 3; i++ ){
		printf("%d ", pop( node ) );
	}
	for ( i = 10; i < 15; i++ ){
		push( node, i );
	}
	for ( i = 0; i < 10; i++ ){
		printf("%d ", pop( node ) );
	}
	printf("\n");

	return 0;
}

程序输出:

10.2-4:

貌似无法实现,否则怎么检查到达链表的尾部??

10.2-5:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

typedef struct NODE{
	struct NODE *next;
	int			data;
} Node;

void insert_node( Node *node, int value )
{
	Node *newnode = ( Node * )malloc( sizeof( Node ) );
	if ( NULL == node->next ){
		newnode->next = NULL;
		newnode->data = value;
		node->next = newnode;
	}
	else{
		while ( NULL != node->next && node->next->data < value ){
			node = node->next;
		}
		if ( NULL == node->next && node->data < value ){
			newnode->next = NULL;
			newnode->data = value;
			node->next = newnode;
		}
		else{
			newnode->next = node->next;
			newnode->data = value;
			node->next = newnode;
		}
	}
}

void delete_node( Node *node, int value )
{
	Node *tempNode = ( Node * )malloc( sizeof( Node ) );
	if ( NULL == node->next ){
		printf("error: empty link list\n");
		return;
	}
	else{
		while ( NULL != node->next && node->next->data < value ){
			node = node->next;
		}
		if ( node->next->data == value ){
			tempNode = node->next;
			node->next = node->next->next;
			free( tempNode );
		}
	}
}

int search_node( Node *node, int value )
{
	while ( NULL != node->next ){
		if ( node->next->data == value ){
			return 1;
		}
		node = node->next;
	}

	return 0;
}

void print_list( Node *node )
{
	node = node->next;
	while ( NULL != node ){
		printf("%d-->", node->data );
		node = node->next;
	}
	printf("NULL\n");
}

int main( void )
{
	int i = 0;
	Node *node = ( Node * )malloc( sizeof( Node ) );
	node->next = NULL;
	node->data = INT_MIN;
	for ( i = 0; i < 10; i += 2 ){
		insert_node( node, i );
	}
	for ( i = 1; i < 10; i += 2 ){
		insert_node( node, i );
	}
	for ( i = 0; i < 12; i += 3 ){
		delete_node( node, i );
	}

	if ( search_node( node, 5 ) ){
		printf(" we find number 5\n");
	}
	else{
		printf(" we do not find number 5\n");
	}

	print_list( node );

	return 0;
}
程序输出:

我第一写的时候,自作聪明,用了以下的方法:

node = node->next;	//略过哨兵头节点
if ( NULL == node ){
	newnode->next = NULL;
	newnode->data = value;
	node = newnode;
}
这实际上是错误的,空节点是特殊的节点,因为它不指向任何的地方,这样写是有问题的.

10.2-7:链表的逆转

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

typedef struct NODE{
	struct NODE *next;
	int			data;
} Node;

Node reverse_list( Node *node )
{
	Node *preNode = ( Node * )malloc( sizeof( Node ) );
	Node *curNode = ( Node * )malloc( sizeof( Node ) );
	Node *nextNode = ( Node * )malloc( sizeof( Node ) );
	if ( NULL == node ){
		free( preNode );
		free( curNode );
		free( nextNode );
		return *node;
	}
	preNode = NULL;
	curNode = node;
	nextNode = node->next;

	while ( NULL != nextNode ){
		curNode->next = preNode;
		preNode = curNode;
		curNode = nextNode;
		nextNode = nextNode->next;
	}
	curNode->next = preNode;
	node = curNode;
	return *node;
}

void print_list( Node *node )
{
	while ( NULL != node ){
		printf("%d-->", node->data );
		node = node->next;
	}
	printf("NULL\n");
}

int main( void )
{
	Node node1 = { NULL, 5 };
	Node node2 = { &node1, 4 };
	Node node3 = { &node2, 3 };
	Node node4 = { &node3, 2 };
	Node node5 = { &node4, 1 };
	Node newnode;

	newnode = reverse_list( &node5 );

	print_list( &newnode );

	return 0;
}
程序输出:

10.2-8:

不知如何下手.........

10.3 指针和对象的实现

用数组来表示链表

10.3-1:

我不知道为什么书本上不按照数组索引的递增顺序排列,而是东一个,西一个的排列方法:

单数组:13 / 4 4 1 7 8 4 10 19 7 13 5 10 16 11 13 /

多数组:

next: 2    3    4     5     6     /

key: 13    4    8     19   5     11

prev:/     1     2    3     4     5

10.3-2:

备注:书上的代码的数组下标都是从索引1开始的,所以需要修改书上的数据:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

int arr[ 24 ];
int stack[ 8 ];
int tail;
int top;

void push( int value ){
	int index = stack[ top ];
	if ( -1 == top ){
		printf("error:full arr\n");
		return;
	}
	top--;
	arr[ index ] = value;
	arr[ index + 1 ] = tail - 2;	//前向指针
	arr[ index + 2 ] = -1;
	arr[ tail ] = index;
	tail = index + 2;
}

int pop()
{
	int result;
	if ( -1 == arr[ tail - 2 ] ){
		printf("error:empty arr\n");
		return INT_MIN;
	}
	result = arr[ tail - 2 ];
	arr[ tail ] = INT_MIN;		//丢弃此节点

	top++;
	stack[ top ] = tail - 2;

	tail = arr[ tail - 1 ] + 2;
	arr[ tail ] = -1;
}

void print_list()
{
	int index = 0;
	while ( -2 != arr[ index ] ){
		index++;
	}
	while ( -1 != arr[ index + 1 ] ){
		printf("%d-->", arr[ index - 1 ] );
		index = arr[ index + 1 ] + 1;
	}
	printf("%d-->NULL\n", arr[ index - 1 ] );
}

int main( void )
{
	int i = 0;
	arr[ 3 ] = 4;
	arr[ 4 ] = 6;
	arr[ 5 ] = 12;
	arr[ 6 ] = 1;
	arr[ 7 ] = -2;			//头节点用-2表示,尾节点用-1表示
	arr[ 8 ] = 3;
	arr[ 12 ] = 16;
	arr[ 13 ] = 3;
	arr[ 14 ] = 18;
	arr[ 18 ] = 9;
	arr[ 19 ] = 12;
	arr[ 20 ] = -1;

	stack[ 0 ] = 0;
	stack[ 1 ] = 9;
	stack[ 2 ] = 15;
	stack[ 3 ] = 21;

	top = 3;
	tail = 20;

	for ( i = 0; i < 5; i++ ){
		push( i );
	}
	print_list();
	for ( i = 0; i < 3; i++ ){
		pop();
	}
	print_list();

	return 0;
}
程序输出:

10.3-5:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

int next[ 8 ];
int key[ 8 ];
int prev[ 8 ];

int tail;
int top;

void push( int value )
{
	top--;
	if ( 0 == top ){
		printf("error:full link list\n");
		return;
	}
	next[ tail ] = tail + 1;
	next[ tail + 1 ] = -1;
	key[ tail + 1 ] = value;
	prev[ tail + 1 ] = tail;
	tail++;
}

int pop()
{
	int result;
	top++;
	if ( 8 == top ){
		printf("error:empty link list\n");
		return INT_MIN;
	}
	result = key[ tail ];
	next[ tail - 1 ] = -1;
	tail--;
}

void print_list()
{
	int i = 0;
	while ( -1 != next[ i ] ){
		printf("%d-->", key[ i ] );
		i++;
	}
	printf("%d-->NULL\n", key[ i ] );
}

int main( void )
{
	int i = 0;
	next[ 0 ] = 1;
	next[ 1 ] = 2;
	next[ 2 ] = 3;
	next[ 3 ] = -1;

	key[ 0 ] = 1;
	key[ 1 ] = 4;
	key[ 2 ] = 16;
	key[ 3 ] = 9;

	prev[ 0 ] = -2;
	prev[ 1 ] = 0; 
	prev[ 2 ] = 1;
	prev[ 3 ] = 2;

	tail = 3;
	top = 4;

	for ( i = 0; i < 5; i++ ){
		push( i * i );
	}
	print_list();
	for ( i = 0; i < 4; i++ ){
		pop();
	}
	print_list();

	return 0;
}
程序输出:

10.4 有根树的表示

10.4-2:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct TREE{
	struct TREE *lchild;
	struct TREE *rchild;
	int			data;
} Tree;

Tree *insert_tree( Tree *tree, int value )
{
	if ( NULL == tree ){
		Tree *newtree = ( Tree * )malloc( sizeof( Tree ) );
		newtree->lchild = NULL;
		newtree->rchild = NULL;
		newtree->data = value;
		tree = newtree;
		return tree;
	}
	if ( value == tree->data ){
		printf("the value is duplited\n");
		return tree;
	}
	else if ( value < tree->data ){
		tree->lchild = insert_tree( tree->lchild, value );
	}
	else{
		tree->rchild = insert_tree( tree->rchild, value );
	}

	return tree;
}

void print_tree_recu( Tree *tree )
{
	if ( NULL != tree ){
		printf("%d-->", tree->data );
		print_tree_recu( tree->lchild );
		print_tree_recu( tree->rchild );
	}
}


int main( void )
{
	int i = 0;
	Tree *tree = ( Tree * )malloc( sizeof( Tree ) );
	tree = NULL;

	for ( i = 5; i > 0; i-- ){
		tree = insert_tree( tree, i );
	}
	for ( i = 6; i < 10; i++ ){
		tree = insert_tree( tree, i );
	}

	print_tree_recu( tree );

	printf("\n");
	return 0;
}
程序输出:

10.4-3:非递归算法:参考wiki

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

typedef struct TREE{
	struct TREE *lchild;
	struct TREE *rchild;
	int			data;
} Tree;

typedef struct STACK{
	struct STACK *next;
	Tree		 *data;
} Stack;

void insert_node( Stack *stack, Tree *node )
{
	Stack *newnode = ( Stack * )malloc( sizeof( Stack ) );
	newnode->data = node;
	newnode->next = stack->next;
	stack->next = newnode;
}

Tree *pop_node( Stack *stack )
{
	Tree *node = stack->next->data;
	stack->next = stack->next->next;

	return node;
}

Tree *insert_tree( Tree *tree, int value )
{
	if ( NULL == tree ){
		Tree *newtree = ( Tree * )malloc( sizeof( Tree ) );
		newtree->lchild = NULL;
		newtree->rchild = NULL;
		newtree->data = value;
		tree = newtree;
		return tree;
	}
	if ( value == tree->data ){
		printf("the value is duplited\n");
		return tree;
	}
	else if ( value < tree->data ){
		tree->lchild = insert_tree( tree->lchild, value );
	}
	else{
		tree->rchild = insert_tree( tree->rchild, value );
	}

	return tree;
}

void print_tree( Tree *tree, Stack *stack )
{
	while ( NULL != stack->next || NULL != tree ){
		if ( NULL != tree ){
			printf("%d-->", tree->data );
			if ( NULL != tree->rchild ){
				insert_node( stack,  tree->rchild );
			}
			tree = tree->lchild;
		}
		else{
			tree = pop_node( stack );
		}
	}
}

int main( void )
{
	int i = 0;
	Tree *tree = ( Tree * )malloc( sizeof( Tree ) );
	Stack *stack = ( Stack * )malloc( sizeof( Stack ) );
	stack->next = NULL;
	stack->data = NULL;

	tree = NULL;

	for ( i = 5; i > 0; i-- ){
		tree = insert_tree( tree, i );
	}
	for ( i = 6; i < 10; i++ ){
		tree = insert_tree( tree, i );
	}

	print_tree( tree, stack );

	printf("\n");
	return 0;
}
程序输出:

10.4-4:

这道题不会做,因为不知道如何用代码去表示"左孩子右兄弟树".


10.2 用链表来表示堆的操作:

支持交集,并集,差集:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>

typedef struct NODE{
	struct NODE *next;
	int			data;
} Node;

void insert_node( Node *node, int value )
{
	Node *newnode = ( Node * )malloc( sizeof( Node ) );
	newnode->data = value;
	if ( NULL == node->next ){
		newnode->next = NULL;
		node->next = newnode;
	}
	else{
		while ( NULL != node->next && node->next->data < value ){
			node = node->next;
		}
		if ( NULL != node->next && value == node->next->data ){
			return;
		}
		else{
			if ( NULL == node->next ){
				newnode->next = NULL;
				node->next = newnode;
				return;
			}
			else{
				newnode->next = node->next;
				node->next = newnode;
			}
		}
	}
}

void union_node( Node *node1, Node *node2, Node *node )
{
	while ( NULL != node1 && NULL != node2 ){
		if ( INT_MIN == node1->data && INT_MIN == node2->data ){		//过滤哨兵节点
			node1 = node1->next;
			node2 = node2->next;
			continue;
		}
		if ( node1->data < node2->data ){
			insert_node( node, node1->data );
			node1 = node1->next;
			continue;
		}
		else if ( node2->data < node1->data ){
			insert_node( node, node2->data );
			node2 = node2->next;
			continue;
		}
		else{
			insert_node( node, node1->data );
			node1 = node1->next;
			node2 = node2->next;
		}
	}
	while ( NULL != node1 ){
		insert_node( node, node1->data );
		node1 = node1->next;
	}
	while ( NULL != node2 ){
		insert_node( node, node2->data );
		node2 = node2->next;
	}
}

void intersection_node( Node *node1, Node *node2, Node *node )
{
	while ( NULL != node1 && NULL != node2 ){
		if ( INT_MIN == node1->data && INT_MIN == node2->data ){
			node1 = node1->next;
			node2 = node2->next;
			continue;
		}
		if ( node1->data < node2->data ){
			node1 = node1->next;
			continue;
		}
		else if ( node2->data < node1->data ){
			node2 = node2->next;
			continue;
		}
		else{
			insert_node( node, node1->data );
			node1 = node1->next;
			node2 = node2->next;
		}
	}
}

void subsection_node( Node *node1, Node *node2, Node *node )
{
	while ( NULL != node1 && NULL != node2 ){
		if ( node1->data < node2->data ){
			insert_node( node, node1->data );
			node1 = node1->next;
		}
		else if ( node1->data > node2->data ){
			node2 = node2->next;
		}
		else{
			node1 = node1->next;
			node2 = node2->next;
		}
	}

	while ( NULL != node1 ){
		insert_node( node, node1->data );
		node1 = node1->next;
	}
}

void print_node( Node *node )
{
	while ( NULL != node->next ){
		printf("%d->", node->next->data );
		node = node->next;
	}
	printf("NULL\n");
}

int main( void )
{
	int i = 0;
	Node *node1 = ( Node * )malloc( sizeof( Node ) );
	Node *node2 = ( Node * )malloc( sizeof( Node ) );
	Node *node = ( Node * )malloc( sizeof( Node ) );
	node1->next = NULL;
	node1->data = INT_MIN;
	node2->next = NULL;
	node2->data = INT_MIN;
	node->next = NULL;
	node->data = INT_MIN;

	for ( i = 0; i < 5; i++ ){
		insert_node( node1, i );
	}
	for ( i = 3; i < 8; i++ ){
		insert_node( node2, i );
	}
	union_node( node1, node2, node );
	print_node( node );

	node->next = NULL;
	node->data = INT_MIN;
	intersection_node( node1, node2, node );
	print_node( node );

	node->next = NULL;
	node->data = INT_MIN;
	subsection_node( node1, node2, node );
	print_node( node );

	return 0;
}
程序输出:


转载于:https://my.oschina.net/voler/blog/168496

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值