线性表习题课

对于顺序表而言,每次在表尾处后插入和删除的速度最快,每次在表头处做插入和删除时,需要移动大量的数据元素,删除和插入操作最慢。而对于单链表刚好相反。因为单链表是顺序存取,挨个遍历;而顺序表可以随机存取

6-5 带头结点的单链表就地逆置 (5 分)(就地:利用原节点,不生成新节点)

本题要求实现一个函数,对带有头结点的单链表进行就地逆置。

把每个元素结点从原链上取下,插在头结点(L->next)的后面。(相当于把所有的元素结点插在空表里)

1.首先让头结点的指针域为NULL,p指向a1。把结点a1(即p所指向的结点)在头结点之后。

(单链表插入结点的操作:先修改插入结点的指针域,p->next=L->next ;再修改前驱结点的指针域L->next=p; )   2.p按照原链下移,重复此操作

 

 

void  reverse ( LinkList L )
{
    LinkList p=L->next;//p指向首元结点
    LinkList q;
    L->next=NULL;//首先将头结点的指针域置为NULL,这句容易忘。否则会运行超时(结点的指针域没有为空指针的了),因为之后我们会把这个链表进行输出,会输出一片0000乱码,运行超时
    while(p)//条件是p不为空,即所有结点都参与循环,遍历链表
    {
        q=p->next;//q暂存一下p的后继,把原先还没修改的p->next送给q
        p->next=L->next;//把p所指向的结点插入到L结点的后面,修改p的指针域
        L->next=p;//修改L的指针域
        p=q;//p按照原链下移
    }
}

if(!L)   return 0;//如果链表是空表,直接return即可
//如果链表不空,让p指向第二个结点,把首元结点的指针域置为空。
//L是头指针,指向首元结点,第二个结点的地址为L->next
p=L->next;L->next=NULL;
while(p)
{ q=p->next;
  //把p所指向结点插入到L所只想结点之前,先修改插入结点的指针域
  p->next=L;L=p;//****************
 p=q;
}

不带头结点的单链表,因为头指针L不断变化,形参必须使用引用参数

 

 

 

此时q所指向的结点就会被删掉(修改p的后继,释放q),

此时p,q的所指向结点的数据域不相等,因为该表是有序表,故后面没有1了,p下移

 

void delsame(LinkList L)
{  p=L->next;//让p指向第一个结点
   if(!P)  return 0;
   while(p->next)//判断p是否有后继,即p->next不为空
   {
      q=p->next;//q为p的后继 
      if(p->data==q->data)//删除q,先修改p的指针域
      {
         p->next=q->next;free(q);
      }
       else
      p=p->next;//p下移

   }
}

 

顺序表的删除,不是删除一个节点就向前移,而是*******

因为k,i所指向结点的数据域相同,所以不把i放在此处,i下移。做完之后,返回k+1

void del(SqList &L)//是引用参数,修改了这个顺序表
{
    k=0;//顺序表,k初始化为下标为0的元素
  for(int i=1;i<L.length;i++)
  {//作比较
    if(L.elem[k]!=L.elem[i])
     {
       L.elem[k+1]=L.elem[i];
        k++;
     }    
     
   }
   if(L.length==0) return 0;//L.length==0,顺序表是空表,没有做删除
   if(L.length>0)   L.length=k+1;
}

 1.插入40的话,就要找40的插入位置,p初始化指向首元结点,q是p的前驱,所以q初始化为指向头结点

2.除了一般情况外,在考虑时,还要考虑链表的两个端点。遍历至p为空后

3.在最前面做插入的话

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值