双链表学习以及复习

双向链表 :

拥有两个方向:

从头到尾/从尾到头

线性结构 + 链式存储

拥有一个数据域 + 两个指针域

其中一个指针域保存下一个节点的地址

另一个指针域保存上一个节点的地址

结构体模板:

typdef struct link{
				int data; //数据域 
				struct link *prev;//前指针域:上一个节点的地址 
				struct link *next;//后指针域:下一个节点的地址
			}link_t,*plink_t;

逻辑操作

1.创建一个节点

plink_t create_node(int d)
{
   plink_t p = (plink_t)malloc(sizeof(link_t));//创建节点p,分配空间
   if(p==NULL)
{
   perror("malloc error");
   return NULL;
   
}

//初始化节点
p->data = d;//将外部传入的d,赋值到节点的数据域上
p->prev=NULL;//目前节点没有进入链表,所以初始化为NULL
p->next=NULL;//目前节点没有进入链表,所以初始化为NULL

return p;

}

建立一个结构体指针用来接收 头节点的地址

plink_t head = link_init();

plink_t link_init(){
 


return creat_node(-1);

}

2.头插操作:新节点固定插入到头节点的后面

void link_insert_head(plink_t p,int d)
{
    //1>通过接收到的数据创建节点
    plink_t node=create_node(d);
    if(node==NULL){
        return;
    }
    
    //2>将node节点插入到 头节点的后面 --->头插 
    insert_tail(p,node);
   
}

2.尾插操作:新节点固定插入到 链表的末尾 

void link_insert_tail(plink_t p,int d)
{
    plink_t node=create_node(d);
    if(node==NULL){
        return;
    }
    //将位置跳转到尾巴
    while(p->next!=NULL)
        p=p->next;
    
    //将节点插入到尾巴
    insert_tail(p,node);

}

将位置跳转到尾巴 p=p->next;

插入函数 关键!!!

void insert_tail(plink_t p,plink_t node)
{
    node->next=p->next;
    node->prev=p;
    if(p->next!=NULL)
        p->next->prev=node;
    p->next=node;
 
}

 /*这里做if判断的作用是:有可能p节点是链表的最末尾节点,由于该链表不是循环链表,所以最末尾节点p节点的下一个节点(即:p->next)为空节点(NULL),由于空节点是没有数据域和指针域的,所以也就不存在下面C语句p->next->prev,所以这里需要判断一下。如果p节点为末尾节点,那么就执行 p->next->prev = node;这句话。如果该链表是循环链表,那么这里就不需要进行if判断了*/
          
原文链接:https://blog.csdn.net/qq_39577221/article/details/124789642

3.遍历双链表中的数据

void display(plink_t p)
{
    printf("遍历结果为:");
    while(p->next!=NULL){
        p=p->next;
        printf("%d ",p->data);
        
    }
    printf("\n");
    
}

4.逆序遍历

void n_display(plink_t p)
{
    printf("逆序遍历结果为:");
    while(p->next!=NULL){
        p=p->next;
    }
    
    while(p->prev!=NULL){
        
        printf("%d ",p->data);
        p=p->prev;
    
    }
    printf("\n");
    
    
}

5.删除操作:通过数据域找到要删除的数据,并删除节点

void link_del(plink_t p,int d)
{
    //1>判断输入的数据,是否满足链表中的某个数据域
    while(p->next!=NULL){
        p=p->next;
        if(p->data==d){//如果满足该条件,说明找到了要删除的数据
            node_del(p);
            return;
        }
        
    }
    printf("助教%d号没有上班\n",d);
}

6.替换操作:根据数据域new创建一个节点,用新节点替换旧节点

void link_update(plink_t p,int old,int new)
{
    //1>遍历查找数据是否存在和old匹配的数据域 
    while(p->next!=NULL){
        p=p->next;
        if(p->data==old){//满足条件,说明找到了
            plink_t new_node=create_node(new);//根据新数据创建新节点
            if(new_node==NULL)
                return;
            update(p,new_node);
            return;
        }
        
    }
    printf("没找到助教%d,换一批\n",old);
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值