Linux与数据结构 2019-3-9 上午

1.复习线性表

1.1 概念:数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的

1.2 线性表分为 链式 和 顺序

1.3 vector 和 list 的区别

1.数据结构不同:
vector 和数组类似,拥有一段连续的内存空间,并且起始地址不变,因此能够进行高效的随机存取;
list 是由双向链表实现的,因此存储空间是不连续的,只能通过指针访问数据;
2.是否能通过下标访问:
vector 可以直接通过下标访问; list 则不能使用下标直接访问;
3.是否支持操作符重载:
vector 拥有一段连续的内存空间,能很好的支持随机存取,因此vector::iterator支持“+”,“+=”,“<”等操作符;
list的内存空间可以是不连续,它不支持随机访问,因此list::iterator则不支持“+”、“+=”、“<”等;
但同时,vector::iterator和list::iterator都重载了“++”运算符;

1.4 实现一个线性表

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

typedef struct list
{
	int nValue;
	struct list *pNext;
}List;

List *CreateList()
{
	List *pHead = NULL;
	List *pTail = NULL;

	List *pTemp = NULL;

	int nNum;
	
	scanf("%d",&nNum);

	if(nNum == 0)return NULL;

	pHead = (List*)malloc(sizeof(List));
	pHead->nValue = nNum;
	pHead->pNext = NULL;
	pTail = pHead;


	scanf("%d",&nNum);
	while(nNum != 0)
	{
		pTemp = (List*)malloc(sizeof(List));
		pTemp->nValue = nNum;
		pTemp->pNext = NULL;

		pTail->pNext = pTemp;
		pTail = pTemp;
		scanf("%d",&nNum);
	}

	return pHead;
}

void Print(List *pHead)
{
	if(pHead == NULL)return;

	while(pHead)
	{
		printf("%d ",pHead->nValue);
		pHead = pHead->pNext;
	}
}

int main()
{
	List *pHead = NULL;
	pHead = CreateList();
	Print(pHead);

	pHead = ReverseList(pHead);
	Print(pHead);

	return 0;
}

1.5 在不破坏单链表结构的情况下倒序打印链表中的元素的方法

1.递归,但递归本身有空间的消耗;
2.来个链表进行头插入;
3.来个数组进行存储;

// ============================================代码未完成============================================

1.6 改变链表的结构,让链表从 1->2->3->4->5 变为 5->4->3->2->1 的方法

1.用一个数组来存储每个元素的地址,再用后一个元素指向前一个元素的地址;
2.使用三个指针,分别指向NULL、1、2,让1指向NULL,将三个指针同时后移,则三个指针分别指向1、2、3,此时再让2指向1,再将三个指针同时后移,以此类推;

// 方法2的实现
#include<stdio.h>
#include<stdlib.h>

... ...

List *ReverseList(List *pHead)
{
	if(pHead == NULL || pHead->pNext == NULL)return pHead;

	List *p1 = NULL;//被指向位置
	List *p2 = NULL;//指向
	List *p3 = NULL;//被断开位置

	p2 = pHead;
	p3 = pHead->pNext;

	while(p3 != NULL)
	{
		p2->pNext = p1;

		p1 = p2;
		p2 = p3;
		p3 = p3->pNext;
	}
	p2->pNext = p1;

	return p2;
}

void ReversePrint(List *pHead)
{
	if(pHead == NULL)return;

	//处理后面节点
	ReversePrint(pHead->pNext);

	//打印当前节点
	printf("%d ",pHead->nValue);
}

int main()
{
	List *pHead = NULL;
	pHead = CreateList();
	//Print(pHead);
	//pHead = ReverseList(pHead);

	//Print(pHead);
	ReversePrint(pHead);
	return 0;
}

1.7 递归倒序打印链表

void ReverseDiGui(List* p_list)
{
	if(p_list != NULL)
		p_list = p_list->pNext;
	printf("%d\n", p_list->nValue)
}

1.8 将链表进行折叠,由1->2->3->4->5->6->7->8变为1->8->2->7->3->6->4->5

// ================================未完成代码=================================

1.9 找到当前链表的倒数第k个节点

1.使用两个指针,第一个先移动k次,第k+1次两个指针开始同时移动,当第一个指针为空时第二个指针所在的位置即为倒数第k个节点的位置;
2.若长度为n,则第n-k个元素的位置即为倒数第k个元素的位置;

// ================================未完成代码=================================

1.10 要删除一个不知道头结点在哪里的元素的方法

1.将要删除的元素 node1 与其下一个 node2 中的东西进行交换(比如node中的id、name等属性),再删除交换后node2位置的节点即可;

// ================================未完成代码=================================

1.11 循环链表

1.特性:从任意节点出发都能遍历整个链表

1.12 静态链表

1.特性:物理结构连续,链表结构离散

1.13 Y型链表(其中的每个值只有一个,不会出现重复值的情况)找交叉点的方法

1.用数组或栈来存储两条链表后,从后部往前取元素,不同元素的上一个元素即为交叉点;

// ================================未完成代码=================================

1.14 判断一个单链表是否有环状结构的方法

1.定义两个指针,一个指针每次移动3个位置,一个指针每次移动1个位置,若这两个指针在某一位置相交,则该链表有环状结构;

// ================================未完成代码=================================

猜你喜欢

转载自blog.csdn.net/weixin_42896619/article/details/88431028