双向链表的创建、插入、删除

C语言实现

/*定义双向链表节点类型*/
typedef struct ListNode{
  int val;
  ListNode *prior;
  ListNode *next;
}ListNode;

/*尾插法创建双向链表——形成与输入相同的序列*/
ListNode* initDulList(){
  //创建头节点、对头节点初始化
  ListNode* head=(ListNode*)malloc(siezof(ListNode));
  head->val=0;
  head->prior=NULL;
  head->next=NULL;
  
  ListNode* p=head;//创建操作指针
  
  for(int i=1;i<5;i++){
    //创建节点并初始化
    ListNode* node=(ListNode*)malloc(siezof(ListNode));
    node->val=i;
    node->prior=NULL;
    node->next=NULL;
    
    //将节点连接到尾部并步进操作指针
    p->next=node;
    p->next->prior=p;
    p=p->next;
  }
  
  return head;
}

/*双向链表中间插入元素和头部插入元素,根据要插入的位置来找到节点*/
ListNode* insertElem(ListNode* head,int elem int location){
  ListNode* dummyHead=(ListNode*)malloc(siezof(ListNode));
  dummyHead->next=head;
  dummyHead->prior=NULL;
  head->prior=dumyHead;
  
  ListNode* p=dummyHead;//为了方便在头节点之前插入
  
  //创建节点封装要插入的数据
  ListNode* insert=(ListNode*)malloc(siezof(ListNode));
  insert->val=elem;
  insert->prior=NULL;
  insert->next=NULL;
  
  for(int i=0;i<location-1;i++){//根据下标位置来插入要用for
    //如果插入尾部
    if(p->next==NULL){
      p->next=last;
      last->prior=p;
      
      return head;
    }
    
    p=p->next;
  }
  
  //如果是插入中间或者头
  ListNode *temp=p->next;
  
  //以节点间隙为单位调整指针
  p->next=insert;
  insert->prior=p;
  insert->next=temp;
  temp->prior=insert;
  
  return head;
}

/*双向链表删除元素,根据要删除节点的值来找到节点*/
ListNode *delElem(ListNode *head,int target){
  ListNode* dummyHead=(ListNode*)malloc(siezof(ListNode));
  dummyHead->next=head;
  dummyHead->prior=NULL;
  head->prior=dumyHead;
  
  ListNode* p=dummyhead;//为了方便删除头节点
  
  while(p!=NULL){//不需要像单链表一样使用前驱节点
    if(p->val==target){
      ListNode* delTemp=p;
        
      p->prior->next=p->next;//不需要像单链表一样创建临时指针
      p->next->prior=p->prior;
      
      free(delTemp);//好习惯
    }
    p=p->next;
  }
  
  return head;
}

/*双向链表查找元素*/
ListNode* findElem(ListNode* head,int target){
  ListNode* p=head;
  
  while(p!=NULL){
    if(p->val==target){
      return p;
    }
    p=p->next;
  }
  
  return NULL;//???没找到是否返回NULL?
}

C++实现

/*双向链表节点类型定义*/
struct ListNode {
  int val;
  ListNode *prior;
  ListNode *next;
  ListNode(int x) : val(x), prior(NULL),next(NULL) {}//将属性初始化
};

class Solution {
public:
  ListNode* deleteNode(ListNode* head, int val) {
    ListNode* dummyNode=new ListNode(-1);
    dummyNode->prior=NULL;
    dummyNode->next=head;
    head->prior=dummyNode;

    ListNode* p=dummyNode;

    while(p!=NULL){
      if(p->val==val){
        ListNode* delTemp=p;//删除用
        p->prior->next=p->next;
        p->next->prior=p->prior;
        delete temp;
      }
      p=p->next;//不能丢
    }

    return dummyNode->next;
  }
};
  1. 将一个新的节点链接到双向链表尾部,先通过位于尾节点的操作指针p将next指针指向新建节点,再通过操作指针p将访问后继节点的prior指针指向自身,就把两个节点之间的指针设置好了,至于新节点的next,在初始化的时候就置空了。
  2. 在双向链表中间插入新建的节点时,由于p、temp、insert三个指针均不用移动且明确,故直接用这三个指针依次对两个间隙的4个指针进行赋值即可。
  3. 双向链表在删除节点时,完全不需要用到前驱节点,而且操作指针时只需要两次操作,建立前驱节点与后继节点之间的联系。
  4. 推荐在删除节点之后,通过节点指针将内存释放。
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务