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个位置,若这两个指针在某一位置相交,则该链表有环状结构;
// ================================未完成代码=================================