链表简介数组:针对索引有语义的情况,利用索引获取值,快速查询。具有随机访问能力的链表:不适合有语义的索引。它是真正动态的,不需要处理固定的容量问题。构建一个节点classe=$e;$this->next=$next;}//将节点对象的元素值输出为字符串publicfunction__toString():string{return(string)$this->e;}}构建链表实现类定义属性和构造函数head=null;$this->size=0;}}获取链表有效元素个数//获取链表有效元素个数publicfunctiongetSize():int{return$this->size;}判断链表是否为空//检查链表是否为空publicfunctionisEmpty():bool{return$this->size===0;}在链表头部插入一个元素//在链表头部插入一个元素publicfunctionaddFrist($e):void{//$nodeObj=新节点($e);//$nodeObj->next=$this->head;//$this->head=$nodeObj;$this->head=newNode($e,$this->head);$这个->大小e++;}在索引位置插入一个元素$e//在索引位置e添加一个新元素//假设链表也有索引publicfunctionadd(int$index,$e):void{if($index<0||$index>$this->size){thrownewRuntimeException('indexvalueiswrong');}if($index===0){$this->addFrist($e);}else{$prev=$this->head;对于($i=0;$i<$index-1;$i++){$prev=$prev->next;}$prev->next=newNode($e,$prev->next);$这个->尺寸++;}}在链表末尾插入一个元素$e//在归档表末尾插入一个元素$epublicfunctionaddLast($e):void{$this->add($this->size,$e);}引入一个虚拟头节点,这样无论链表中哪个节点插入元素,逻辑都是一样的头=空;$this->dummyHead=newNode(null,null);$this->size=0;}//在链表头部插入一个元素//publicfunctionaddFrist($e):void//{////$nodeObj=newNode($e);////$nodeObj->next=$this->head;////$this->head=$nodeObj;//$this->head=newNode($e,$this->head);//$this->size++;//}//添加到索引位置一个新元素e//为了理解和练习,假设链表也有索引//publicfunctionadd(int$index,$e):void//{//if($index<0||$index>$this->size){//thrownewRuntimeException('indexvalueiswrong');//}//if($index===0){//$this->addFrist($e);//}else{//$prev=$this->head;//for($i=0;$i<$index-1;$i++){//$prev=$prev->next;//}}//$prev->next=newNode($e,$prev->next);//$this->size++;//}//}//添加一个新元素到索引位置epublicfunctionadd(int$index,$e):void{if($index<0||$index>$this->size){thrownewRuntimeException('索引值错误');}$prev=$this->dummyHead;对于($i=0;$i<$index;$i++){$prev=$prev->next;}$prev->next=newNode($e,$prev->next);$this->size++;}//在归档列表的末尾插入一个元素$epublicfunctionaddLast($e):void{$this->add($this->size,$e);}//在链表头部插入一个元素publicfunctionaddFrist($e):void{$this->add(0,$e);}}Setindexbit的值为e//Setindexbit的元素值//辅助理解和练习,假设是链表还有一个indexpublicfunctionset(int$index,$e):void{if($index<0||$index>=$this->size){thrownewRuntimeException('索引值错误');}//使用虚拟头节点的下一个元素作为起始位置$cur=$this->dummyHead->next;对于($i=0;$i<$index;$i++){$cur=$cur->next;}$cur->e=$e;}查找元素是否存在//查找链表中是否存在元素$epublicfunctioncontains($e):bool{//使用虚拟头节点的下一个元素作为起始位置$cur=$this->dummyHead->next;while($cur!==null){if($cur->e===$e){返回真;}$cur=$cur->下一个;}returnfalse;}删除元素//删除索引位置的元素值,并返回删除的元素值//帮助理解和练习,假设链表也有索引publicfunctionremove(int$index){if($index<0||$index>=$this->size){thrownewRuntimeException('索引值错误');$prev=$this->dummyHead;对于($i=0;$i<$index;$i++){$prev=$prev->next;}$retNode=$prev->next;$prev->next=$retNode->next;$retNode->next=null;$this->size--;return$retNode->e;}//移除第一个元素publicfunctionremoveFrist(){return$this->remove(0);}//移除最后一个元素publicfunctionremoveLast(){return$this->remove($this->size-1);}对象到字符串魔法方法publicfunction__toString():string{$string='';$cur=$this->dummyHead->next;while($cur!==null){$string.=($cur.'->');$cur=$cur->下一个;}$string.='NULL';return$string;}完整代码head=null;$this->dummyHead=newNode(null,null);$this->size=0;}//获取链表有效元素个数publicfunctiongetSize():int{return$this->size;}//链表是否为空publicfunctionisEmpty():bool{return$this->s大小===0;}//在链表的头部插入一个元素//publicfunctionaddFrist($e):void//{////$nodeObj=newNode($e);////$nodeObj->next=$this->head;////$this->head=$nodeObj;//$this->head=newNode($e,$this->head);//$this->size++;//}//在索引位置添加一个新元素e//为了理解和练习,假设链表也有索引//publicfunctionadd(int$index,$e):void//{//if($index<0||$index>$this->size){//thrownewRuntimeException('indexvalueiswrong');//}//if($index===0){//$this->addFrist($e);//}else{//$prev=$this->head;//for($i=0;$i<$index-1;$i++){//$prev=$prev->next;//}}//$prev->next=newNode($e,$prev->next);//$this->size++;//}//}//添加到索引位置一个新元素epublicfunctionadd(int$index,$e):void{if($index<0||$index>$this->size){thrownewRuntimeException('索引值错误');}$prev=$this->dummyHead;对于($i=0;$i<$index;$i++){$prev=$prev->next;}$prev->next=newNode($e,$prev->next);$this->size++;}//在归档表末尾插入元素$epublicfunctionaddLast($e):void{$this->add($this->size,$e);}//在链表头部插入一个元素publicfunctionaddFrist($e):void{$this->add(0,$e);}//获取索引位置的元素值//辅助理解和练习,假设链表也有索引publicfunctionget(int$index){if($index<0||$index>=$this->size){thrownewRuntimeException('索引值错误');}//使用虚拟头节点的下一个元素作为起始位置$cur=$this->dummyHead->next;for($i=0;$i<$index;$i++){$cur=$cur->next;}返回$cur->e;}//获取链表的第一个元素publicfunctiongetFrist(){return$this->get(0);}//获取链表的最后一个元素publicfunctiongetLast(){return$this->get($this->size-1);}//设置索引位置的元素值//为了帮助理解和练习,假设链表也有索引publicfunctionset(int$index,$e):void{if($index<0||$index>=$this->size){thrownewRuntimeException('ind前值是错误的');}//使用虚拟头节点的下一个元素作为起始位置$cur=$this->dummyHead->next;对于($i=0;$i<$index;$i++){$cur=$cur->next;}$cur->e=$e;}//查找链表中是否有元素$epublicfunctioncontains($e):bool{//使用虚拟头节点$cur的下一个元素=$this->dummyHead->next;while($cur!==null){if($cur->e===$e){返回真;}$cur=$cur->下一个;}返回假;}//删除索引位置的元素值,并返回删除的元素值//辅助理解和实践,假设链表也有索引publicfunctionremove(int$index){if($index<0||$index>=$this->size){thrownewRuntimeException('索引值错误');$prev=$this->dummyHead;对于($i=0;$i<$index;$i++){$prev=$prev->next;}$retNode=$prev->next;$prev->next=$retNode->next;$retNode->next=null;$this->size--;return$retNode->e;}//删除第一个元素publicfunctionremoveFrist(){return$this->remove(0);}//删除最后一个元素publicfunctionremoveLast(){return$this->remove($this->size-1);}公共函数__toString():字符串{$string='';$cur=$this->dummyHead->next;while($cur!==null){$string.=($cur.'->');$cur=$cur->下一个;}$string.='NULL';返回$字符串;}}测试需要DIR。'/LinkedList/LinkedList.php';$linkedListObj=新链表();对于($i=0;$i<5;$i++){$linkedListObj->addFrist($i);echo$linkedListObj;}$linkedListObj->add(2,'abc');echo$linkedListObj;$linkedListObj->removeLast();echo$linkedListObj;$linkedListObj->removeFrist();echo$linkedListObj;$linkedListObj->删除(2);echo$linkedListObj;时间复杂度添加操作addLast()是O(n)addFirst()是O(1)add()是O(n/2)~O(n)删除操作removeLast()是O(n)removeFirst()是O(1)remove()是O(n/2)~O(n)修改操作set()是O(n)查找操作get()是O(n)contains()是O(n)增加:O(n)delete:O(n)change:unknownindexO(n)search:unknownindexO(n)如果只增删改查链表头,都是O(1)
