基础数据结构 双向循环链表以及单链表习题

在这里插入图片描述

双向循环链表.cpp

#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include "dclist.h"
/*
作业1:补全双向循环链表代码
作业2:单链表习题
*/

//循环链表可执行的操作:(增删改查)
//初始化
void Init_dclist(PDClist pl)
{
	assert(pl != NULL);
	if(NULL == pl)
		return;

	//pl->data; 头结点的数据域不使用 浪费掉
	pl->next = pl;
	pl->prior = pl;
}

//头插
bool Insert_head(PDClist pl, int val);

//尾插
bool Insert_tail(PDClist pl, int val);

//按位置插入
bool Insert_pos(PDClist pl, int pos, int val);

//头删
bool Del_head(PDClist pl);

//尾删
bool Del_tail(PDClist pl);

//按位置删除
bool Del_pos(PDClist pl, int pos);

//按值删除,删除遇到的第一个值为val的节点 如果值为val的节点不存在,则返回false
bool Del_val(PDClist pl, int val);

//查找  查找值为val的第一个节点,找到则返回其节点地址,否则返回NULL
PDClist Search(PDClist pl, int val);

//判空
bool IsEmpty(PDClist pl);

//获取循环链表有效元素个数
int Get_length(PDClist pl);

//打印
void Show(PDClist pl);

//清空
void Clear(PDClist pl);

//销毁1 一直头删的方式释放内存
void Destroy(PDClist pl);

//销毁2
void Destroy2(PDClist pl);

//寻找值为val的节点的前驱
PDClist Get_prior(PDClist pl, int val);

//寻找值为val的节点的后继
PDClist Get_next(PDClist pl, int val);

单链表 习题
在这里插入图片描述

第一题 单链表逆置 掌握 “一直头插”。

void Reverse(PNode plist)
{
//assert 头节点存在 
Node*p=plist->next;//让p指向第一个有效节点的位置(但这个位置有可能NULL)
Node*q=NULL;
plist->next=NULL;//或者调用初始化函数让next变为NULL
while(p!=NULL)
 {
 q=p->next;
  Insert_head(plist,p->data)
  free(p);
  p=q;
 }
}
int main()//测试程序
{
Node head;
Init_list(&head);
for(int i;i<0;i++)
 {
 Insert_pos(&head,i,i+1)
 }
 show(&head);
  Reverse(&head);
}

第二题 单链表删除任意一点o(1)时间复杂度完成
用 狸猫换太子 下一个节点替我受死。

bool DelPoint(PNode plist,PNode point)//把后面一个节点 给到前面 但不能删除最后一个节点
{
assert(plist!== NULL && point!== NULL);
if(plist == NULL || point == NULL);
return false;
if(point->next == NULL)//删除节点时尾节点 按位置删
 {
 return Del_pos(plist,Get_length(plist)-1)
 }
 Node*p=point->next;
 point->data=p->data;
 point->next=p->next;
 free(p);
 p = NULL;
 return true}

第三题 判断两单链表是否相交 有的话将第一个交点返回
两单链表只会存在题目三这种相交

//只判断两个单链表是否相交?
//只要相交 他两的尾巴一定相同 让两个指针都跑到尾节点 比较是否是一个节点即可。
Node*Intersect(PNode plist1,plist2)
{

//assert
int len1=Get_length(plist1);
int len2=Get_length(plist2);//知道长度 让长的先走

Node*p=len1>len2?plist1:plist2
Node*q=len1>len2?plist2:plist1;

for(int i=0;i<abs(len1-len2);i++)//abs求绝对值
 {
  p = p->next;//代表长的向后跑
 }//len相同则不循环
//此时 p q长度一致
 while(p!=NULL//跑到结尾
 {
 if(p=q)
  {
  return p;
  }
  p=p->next;
  q=q->next;
 }
 return NULL//没相交 返回空
}

第四题 获取单链表倒数第k个节点

PNode GetendK(PNode plist,int k)
{
assert(plist!=NULL && k>0 && k<=getlength(plist));
if(plist=NULL||k<=0||k>Get_length(plist))
return NULL;

Node*p=plist;
Node*q=plist;
 for(int i=0;i<k;i++)//倒数第k个 先让p往后走k步
  {
  p=p->next;
  }
  while(p!=NULL)//
  {
  p=p->next;
  q=q->next;
  }
  return q;
}

第五题 两个指针 跑的速度不一样 存在环就会相遇
判断单链表是否存在环 如果存在将入环的点返回
在这里插入图片描述
在这里插入图片描述

void IsLoop(PNode plis)
{
assert(plist!=NULL);
if(plist==NULL)
return NULL;
//在分别定义一快一慢指针
Node*fast=plist;//快指针 一次走两步
Node*slow=plist;//慢指针 一次走一步
//一直跑 没环 快的先到终点 有环 则遇到
while1//死循环
 {
 if(fast=NULL||fast->next=NULL//fast第一步为空 或者 走两步为空都代表没有环
  {
  return NULL}
  fast = fast->next->next;
  slow = slow->next;
  if(fast == slow)//有环
   {
   break}
 }
}//死循环三种退出方式 fast第一步为空或者 第二部为空 则代表没有环 ;fast最终追上了slow 则代表有环 两者相遇。
Node*p=plist;
Node*q=fast;//Node*q=slow;
 while(p!=q)//从头开始跑 从节点开始跑
 {
 p=p->next;
 q=q->next;
 }
 return p;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值