小白算法积累——单链表23#带头结点单链表+删除绝对值相同的结点

题目:用单链表保存m个整数,结点的结构为【data】【link】,且**|data|<=n(n为正整数)。现要求设计一个时间复杂度尽可能高效**的算法,对于链表中data的绝对值相等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。
例如,若给定的单链表head如下:
小白算法积累——单链表23#带头结点单链表+删除绝对值相同的结点_第1张图片

关键字:带头结点单链表+删除绝对值相同的结点

思路
关注:
要求时间高效,所以想到用空间换时间,建立辅助数组来存放符合条件的新链表

(* ̄(oo) ̄):不是存放新链表!而是记录旧链表中已出现的数值,方法是:利用位序来代表某个元素的绝对值和0/1来代表是否存在。从而只需对原表进行一趟扫描。

因为|data|<=n,故辅助数组q的大小为n+1,各元素的初值均为0。
依次扫描链表中的各结点,同时检查q|data|的值,若为0则保留该结点,并令q|data|=1,否则将该结点从链表中删除

typedef struct node{
   int data;
   struct node *next;
   }LNode;

void func(PNODE L,int n)//一个删除绝对值相同的结点的函数
{  PNODE p=L,r;//p为原表工作遍历指针,r为  指针
   int *q,m;//q为指向新链表的指针,m为绝对值相同的元素的实际值(相同或相反)
   q=(int*)malloc(sizeof(int)*(n+1));//给q所指向的新链表开辟空间,带头结点的一个长度为n,总长为n+1
   for(int i=0;i<n+1;i++)//当i=0~n时,共计n+1次来进行以下操作
      *(q+i)=0;//给q的n+1个元素全部赋值为0
   while(p->next!=NULL)//p开始遍历原表
   {m=p->next->data>0?p->next->data:-p->next->data;//m的值从第一个原表结点的值开始遍历,作用是将原表中所有的值全部改成其绝对值(正值)。
     if(*(q+m)==0)//判断该结点的data是否出现:等于0,没有出现过,可以保留,但是要留档,之后再遇到要被删除;等于1,则出现过,需要被删除
     {  *(q+m)=1;//留档
        p=p->next;
      }
      else
      {  r=p->next;//删掉p的后继结点
         p->next=r->next;
         free(r);
      }
    }
    free(q);//最后释放*绝对值存在与否辅助*记录表
  }

你可能感兴趣的:(小白算法积累)