04、线性表案例1:线性表转置

题源及算法思路来源于“网易云课堂:数据结构实战完全手册(夏曹俊·丁宋涛)”

线性表转置的需求

  设有一个线性表,其数据为a、b、c、d、e、f、g,要求将其就地转置成g、f、e、d、c、b、a,且逆转表仍占据原表空间。分别使用顺序表和单链表进行实现

线性表转置的顺序表实现

#include 
#include "SequentialList.h"

SequentialList* pGlobalSqList;

// 顺序表转置函数
void ReverseSqList(SequentialList* pSqList)
{
	int temp;// 两个变量转置时所用的临时变量
	int count;// 存储用于折半转置的次数
	int i;// 计数器

	if (pSqList->last == 0 || pSqList->last == 1)// 若顺序表为空或仅有一个元素,则直接返回
	{
		return;
	}

	count = pSqList->last / 2;// 获取折半转置的次数

	for (i = 0; i < count; i++)// 执行转置
	{
		temp = pSqList->data[i];
		pSqList->data[i] = pSqList->data[pSqList->last - 1 - i];
		pSqList->data[pSqList->last - 1 - i] = temp;
	}
}

int main()
{
	pGlobalSqList = InitializeSqList();// 初始化顺序表

	for (int i = 0; i < 10; i++)// 顺序表插入内容
	{
		InsertSqListElement(pGlobalSqList, i * 2, i);
	}
	TraversalSqList(pGlobalSqList);

	ReverseSqList(pGlobalSqList);
	TraversalSqList(pGlobalSqList);

	free(pGlobalSqList);

	return 0;
}

线性表转置的单链表实现

#include 
#include "LinkList.h"

// 单链表转置函数
LinkListNode* ReverseLinkList(LinkListNode* pHead)
{
	/* 操作目标:转置单链表中所有结点之间的联系,让最后一个数据结点成为第一个数据结点
			 让倒数第二个数据结点成为第二个数据结点,依此类推,并让转置前的最后一个数
			 据结点成为头结点的直接后继结点
	*/		 

	LinkListNode* pTemp = NULL;// 表示当前单链表结点的临时结点
	LinkListNode* pTempPre = NULL;// 表示当前单链表节点在当前更新前的直接前驱结点的临时结点
	LinkListNode* pTempNext = NULL;// 表示当前单链表节点在当前更新前的直接后继结点的临时结点

	pTempPre = pHead;// 由于从头结点开始遍历,第一个数据结点的直接前驱结点是头节点
	pTemp = pTempPre->pNext;// 将第一个数据结点选作当前单链表结点的临时结点

	// 在不改变每个数据结点的pNext指针域的情况下,切断头结点与单链表的链接并将前两个结点转置
	pTempNext = pTemp->pNext;// 当前结点的直接后继结点就是第二个数据结点
	pTemp->pNext = pTempPre;// 使头结点成为第一个数据结点的直接后继结点
	pTempPre = pTemp;// 使第一个数据结点成为当前临时结点更新后的直接前驱结点
	pTemp = pTempNext;// 使第二个数据结点成为当前的临时结点

	while (pTemp->pNext != NULL)// 从第二个数据结点开始遍历单链表,并执行转置
	{
		pTempNext = pTemp->pNext;// 使当前结点的直接后继结点成为临时后继结点
		pTemp->pNext = pTempPre;// 使上一次更新得到的数据结点的直接前驱结点成为当前结点的后继结点
		pTempPre = pTemp;// 使当前结点成为下一次更新得到的当前结点的直接前驱结点
		pTemp = pTempNext;// 当前结点的直接后继结点成为下次更新所用的当前结点
	}

	pTemp->pNext = pTempPre;// 使最后一个结点的pNext指针域指向其原本的直接前驱结点

	// 转置完毕,重新设置头结点与单链表的联系
	pHead->pNext->pNext = NULL;// 此时头结点的直接后继结点已经是单链表的最后一个结点,所以通过头结点将其指针域置为空
	pHead->pNext = pTemp;// 将头结点的指针域指向当前单链表的第一个结点(即转置前的最后一个结点)

	return pHead;
}

int main()
{
	LinkListNode* pHead = NULL;

	pHead = CreateLinkListTail(10);

	TraversalLinkList(pHead);

	pHead = ReverseLinkList(pHead);

	TraversalLinkList(pHead);

	ClearLinkList(pHead);

	system("pause");

	return 0;
}

你可能感兴趣的:(数据结构,学习笔记)