数据结构专题(二):2.7顺序表反转

思想:
单链表中体现数据结构学习中的一个重要的算法操作思想。就是要学习这些数据元素的联系规律,如何传递结点中的next域,在单链表中,有且只有一个作用记录了联系,这个就是当前结点的next存储了下一个结点的地址。
数据结构专题(二):2.7顺序表反转
结论:只要我们在设计这些元素运动的重复过程(写循环),这些元素的相对位置不发生变化,那么这个过程就是可以重复的。
如下代码:使用两种方法进行顺序链表的转换。

#include <stdio.h>
#include <stdlib.h>
//链表中节点的结构
typedef struct Link {
	int  elem;
	struct Link *next;
}link;
//初始化链表的函数
link * initLink();
//用于输出链表的函数
void display(link *p);
//迭代法反转链表
link * iteration_reverse(link* head);
//头插法反转链表
link * head_reverse(link * head);
//就地逆置法反转链表
link * local_reverse(link * head);

int main() {
	link*p = NULL;
	//初始化链表(1,2,3,4)
	printf("初始化链表为:\n");
	p = initLink();
	display(p);

	p = iteration_reverse(p);
	display(p);

	p = head_reverse(p);
	display(p);

	p = local_reverse(p);
	display(p);
	return 0;
}

link * initLink() {
	int i = 0;
	link * temp = NULL;
	link * p = (link*)malloc(sizeof(link));//创建头节点
	//首元节点先初始化
	p->elem = 0;
	p->next = NULL;
	temp = p;//头指针指向头节点
	for (i = 1; i < 5; i++) {
		link *a = (link*)malloc(sizeof(link));
		a->elem = i;
		a->next = NULL;
		temp->next = a;
		temp = temp->next;
	}
	return p;
}
//迭代反转法,head 为有头节点链表的头指针
link * iteration_reverse(link* head) {
	//如果该链表为 NULL,或者没有存储数据,又或者只存有 1 个数据
	if (head == NULL || head->next == NULL || head->next->next == NULL) {
		return head;
	}
	else {
		link * beg = NULL;
		link * mid = head->next;
		link * end = head->next->next;
		//一直遍历
		while (1)
		{
			//修改 mid 所指节点的指向
			mid->next = beg;
			//此时判断 end 是否为 NULL,如果成立则退出循环
			if (end == NULL) {
				break;
			}
			//整体向后移动 3 个指针
			beg = mid;
			mid = end;
			end = end->next;
		}
		//最后修改 head 头指针的指向
		head->next = mid;
		return head;
	}
}
//头插法反转链表
link * head_reverse(link * head) {
	//为新节点添加头节点
	link * new_head = (link*)malloc(sizeof(link));
	new_head->elem = 0;
	new_head->next = NULL;
	link * temp = NULL;
	if (head == NULL || head->next == NULL || head->next->next == NULL ) {
		return head;
	}
	while (head->next != NULL)
	{
		temp = head->next;
		//将 temp 从 head 中摘除
		head->next = head->next->next;

		//将 temp 插入到 new_head 的头部
		temp->next = new_head->next;
		new_head->next = temp;
	}
	return new_head;
}
//就地逆置法
link * local_reverse(link * head) {
	link * beg = NULL;
	link * end = NULL;
	if (head == NULL || head->next == NULL || head->next->next == NULL) {
		return head;
	}
	beg = head->next;
	end = head->next->next;
	while (end != NULL) {
		//将 end 从链表中摘除
		beg->next = end->next;
		//将 end 移动至链表头
		end->next = head->next;
		head->next = end;
		//调整 end 的指向,另其指向 beg 后的一个节点,为反转下一个节点做准备
		end = beg->next;
	}
	return head;
}

void display(link *p) {
	link* temp = p->next;//将temp指针重新指向首元结点
	//只要temp指针指向的结点的next不是Null,就执行输出语句。
	while (temp) {
		printf("%d ", temp->elem);
		temp = temp->next;
	}
	printf("\n");
}
上一篇:1.8 表单、表格和高度塌陷


下一篇:CentOS7+hadoop2.6.4+spark-1.6.1