当前位置: 首页 > 后端技术 > PHP

数据结构的单向循环链表

时间:2023-03-30 02:28:54 PHP

介绍和单向链表的唯一区别是链表的最后一个节点指向链表的头节点。案例:单向循环链表的经典案例是约瑟夫环问题。引申为类似猴子选王、扔手帕等都是约瑟夫的真实场景。假设有编号为1,2,3...n的人围成一圈,编号为k(1<=k<=n)的人开始数数,数到m的人出列,他的下一个人从1开始数,数到m的人出队,以此类推,直到所有人都出队,这样就产生了出队的数列。构造一个节点类,每个节点代表一个人,节点包含数字和下一个字段类Node{public$no;公共$下一个;公共函数__construct($no){$this->no=$no;}}创建一个单向循环链表ClassclassCircleLinkedList{public$first;}生成一个单向循环链表,长度为total,其中需要两个变量$first和$cur,$first指向头部链表的节点,$cur指向当前链表的最后一个节点。公共函数addNode($total){$cur=null;//循环插入$total个节点for($i=1;$i<=$total;$i++){$boy=newNode($i);if($i==1){//如果它是第一个节点,则将$first指向它。$this->first=$boy;$cur=$男孩;}else{//新人的next字段指向第一个人,围成一个圈。$boy->next=$this->first;//将$cur移回新人$cur->next=$boy;$cur=$男孩;跳出圈子的想法:创建两个变量$temp和$helper,现在将$temp指向$first,将$helper指向链表中的最后一个人。将$temp和$helper都移动k-1位以找到开始计数的人。当$temp开始计数时,$temp和$helper同时移动$num位。最后,$helper的next字段指向$temp的next,$temp向后移动一位,即出列完成。循环第二步,直到$temp==$helper表示链表只剩下一个人,出队完成。publicfunctionleaveCircle($k,$num){//现在将$temp指向$first$temp=$this->first;//然后通过遍历将$temp指向链表中的最后一个人。while(true){if($temp->next==$this->first){中断;}$temp=$temp->下一个;}//$temp和$helper移动k-1个位置来找到开始计数的人($i=0;$i<$k-1;$i++){$this->first=$this->first->下一步;$temp=$temp->下一个;}//循环while(true){//如果$first==$temp表示链表只剩下一个结点,则退出循环if($this->first==$temp){break;}//开始计数,$temp和$helper开始移动for($i=0;$i<$num-1;$i++){$this->first=$this->first->next;$temp=$temp->下一个;}//$this->first指向报号结束后的人echo"\n".“号码是”。$这个->首先->没有。“圈外人”;//将当前指针$first移动到下一个,然后让$temp的next指向$first完成循环$this->first=$this->first->next;$temp->next=$this->first;}回声“\n”。“最后一人的号码是:”。$this->first->no;}