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;
}
程序输出: