Bootstrap

c语言逆向输出链表中的值

这道题其实挺简单的,不过为了拓宽思路,这里我来记录三个方法

?1 通过将其按照头插法插入另一个链表中,然后顺序输出新链表值就行。这个也是我们的常规思路啦

//先倒序存到一个新的链表中,然后输出
//采用头插法即可
void reverse_output(Node* head)
{
	Node* reverse_first = (Node*)malloc(sizeof(Node));
	assert(reverse_first);

	reverse_first -> data = 0;
	reverse_first -> next = NULL;

	Node* p = head->next;

	while(p)
	{
		Node* save = p;
		p = p->next;
		save->next = reverse_first->next;
		reverse_first->next = save;

	}

	print_list(reverse_first);




}

?2 由于是逆序,所以我们就很自然的想到用栈来实现啦,这里我借助的是顺序栈

//从尾到头,反向输出每个节点的值
//借助栈来实现

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

#define true 1
#define false 0
#define STACK_MAXSIZE 100
#define STACK_INCREMENT 10

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

}Node;

//用顺序存储栈
typedef struct Stack
{
	int* base;
	int* top;
	int stacksize;

}Sqstack;

void InitStack(Sqstack* S)
{
	S->base = (int* )malloc(STACK_MAXSIZE * sizeof(int));      
	if(!S->base)
		printf("ERROR!\n");

	S->top = S->base;
	S->stacksize = STACK_MAXSIZE;
}

int StackEmpty(Sqstack S)
{
	if(S.top == S.base)
		return true;
	else
		return false;
}

//压入和弹出的时候top指针的先后顺序很重要的
void push(Sqstack* S,int e)
{
	if(S->top - S->base >= S->stacksize)
	{
		S->base = (int *)realloc(S->base,
			(S->stacksize + STACK_INCREMENT)* sizeof(int));

		assert(S->base);
		S->stacksize += STACK_INCREMENT;
		S->top = S->base + S->stacksize;
	}

	*(*S).top = e;  //top指向的是压入栈的元素的位置

	S->top ++;
}

void pop(Sqstack* S)
{
	int e;
	if(StackEmpty(*S) == 0)
	{
		S->top --;
		e = *(*S).top;
		printf("%d ", e);
	}

	else
		printf("Stack is empty!\n");

}


void print_list(Node* head);

Node* Init_List()
{
	Node* head = (Node*)malloc(sizeof(Node));
	assert(head);

	int first,size;

	printf("please enter list sizes: ");
	scanf("%d",&size);


	head->data = 0;
	head->next = NULL;

	//采用尾插法,构建链表
	//则需要构建一个链表的尾指针
	Node* tail = head;

	for(int i = 0; i < size ; i++)
	{
		Node* new = (Node*)malloc(sizeof(Node));
		assert(new);

		scanf("%d",&first);
		new -> data = first;
		tail-> next = new;
		new -> next = NULL;
		tail = tail->next;

	}

	return head;

}


void reverse_list(Node* head,Sqstack* S)
{
	Node* p = head->next;

	while(p)
	{
		push(S,p->data);
		p = p->next;
	}

	while(S->top != S->base)
		pop(S);      //pop是指向栈的前一个元素,当他弹出时,他是直接减1,然后弹出,所以直接S->top != S->base,也可以弹出栈底部元素
	printf("\n");

}


void print_list(Node* head)
{
	Node* p ;
	p = head->next;

	while(p != NULL)
	{
		printf("%d ", p->data);
		p = p->next;
	}

	printf("\n");

}


int main(int argc, char const *argv[])
{
	Node* list = Init_List();
	int number;
	Sqstack S;
	InitStack(&S);

	reverse_list(list,&S);
	

	

	return 0;
}

?3 最简单的一种方法来啦,既然都想到用栈啦,那就很自然想到用递归来实现。即每当访问一个节点的时候,先递归输出它后面的节点,在输出自身的节点,这样链表就反向输出啦

void reverse_output(Node* head)
{
	Node* p = head;
	if(p->next != NULL)
		reverse_output(p->next);

	printf("%d ", p->data);

	printf("\n");

}

? 当然还可以用最大堆来实现啊。不过链表不存在随机访问的能力,所以,我们就需要先把链表中的值存到数组中,然后调整到最大堆后,然后再取出元素。由于这道题用最大堆有点牛刀小试,就不写了

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;