单链表解析Ⅰ

对链表某个节点的操作除第一个节点外,都需要找到该节点的前驱节点,这是关键。

1.不带头结点单链表:
①定义

typedef char ListData;
typedef struct node
{
    ListData data;
    struct node * link;
}ListNode;

typedef ListNode * LinkList;
LinkList first; //定义头指针
LinkList last;  //定义尾指针

②插入:没有头结点插入有三种情况
(1)在第一个节点前插入
在第一个节点前插入
(2)在链表中间插入
在链表中间插入
(3)在链表末尾插入
在链表末尾插入

/* 参数列表:
** LinkList & first:进行操作的链表头指针,
** x:插入的数据,
** i:插入的位置
*/
void Insert(LinkList & first,int x,int i)
{
    ListNode * p = first ;  //用指针p接收插入节点的上一个节点
    int k = 0;
    while(p!=NULL&&k<i-1)  //p节点不为空节点并且还为找到i的位置
    {
        p = p->link;  //遍历链表,找到第i-1个节点,用p指针接收
        k++;
    }
    if(p==NULL&&first!=NULL)  //不是空链表且遍历完链表没有找到第i-1个节点
    {
        printf("无效的插入位置\n");
        return 0;
    }

//找到了第i-1个节点
    //创建新节点 malloc返回值类型为(void *)强制转换为(LinkNode *)类型
    ListNode * newNode = (ListNode *)malloc(sizeof(ListNode));

    newNode->data = x;  //添加数据
    if(first==NULL||i=0)  //如果是空链表或者插入位置为头指针后
    {
        //新节点指针域指向头指针指向的节点(也就是第一个节点),或者空链表NULL,新节点也成为第一个节点。
        newNode->link = first;
        //如果为空链表,则新节点也是尾节点
        if(first==NULL) last = newNode;
        //头指针指向新的第一个节点
        first = newNode;
    }else{  //在中间或者末尾插入
        //新节点的指针域指向p节点的下一个节点
        newNode->link = p->link;
        //如果p是最后一个节点,尾指针指向新节点
        if(p->link==NULL) last = newNode;
        //p的指针域指向新节点
        p->link = newNode;
    }
    return 1;
}

③删除
删除节点

/*  参数链表
**  first:链表头指针
**  i:要删除的节点
*/  
int Delete(LinkList & first,int i)
{
    ListNode *p,*q;  //用q指针指向删除的节点,以便释放
    if(i==0)  //删除第一个结点
    {
        q = first;   //first指向的节点,即第一个节点 
        first = first->link;  //将first指向原节点的下一个节点
    }else{
        p = first;
        int k = 0;
        while(p!==NULL&&k<i-1)
        {
            p = p->link;  
            k++;   //遍历链表,直到p为空或是找到第i-1个节点
        }
        if(p==NULL||p->link==NULL)  //没找到第i-1个节点但是链表结束了
        {
            printf("无效的删除位置\n");
            return 0;
        }else{
            q = p->link;
            p->link= q->link;
        }
        if(q==last){   //如果p->link节点是尾节点
            last = p;  //尾指针指向p指针指向的节点
        }
        k = q->data;  //用k接收删除节点的数据域
        free(q);   //释放q指针指向的内存空间
        return k;  //返回删除的数据
    }
}

2.带头结点的单链表
①插入
插入节点
/* 参数列表
** first:链表头指针
** x:插入节点数据域
** i:插入的位置
*/

int Insert(LinkList first,ListData x,int i)
{
    ListNode * p;
    int k = 0;
    while(p!=NULL&&k< i-1)
    {
        p = p->link;
        k++;
    }
    if(p==NULL){
        printf("无效的插入位置\n");
        return 0;
    }
    ListNode * newNode = (ListNode *)malloc(sizeof(ListNode));
    newNode->data = x;
    newNode->link = p->link;  //新节点指针域指向p的后继
    p->link = newNode;   //p的后继为插入的节点
    return 1;
}

②删除
删除节点

int Delete(ListLink first,int i)
{
    ListNode * p ,*q;
    int k = 0;
    while(p!=NULL&&k< i-1)
    {
        p = p->link;
        k++;
    }
    if(p==NULL||p->link==NULL){
        printf("无效的删除节点\n");
        return 0;
    }
    q = p->link;  //找到第i-1个节点,将指针p指向该节点的后继
    p->link = q->link;  //将第i-1个节点的指针域指向原本后继的后继
    free(q);
    return 1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值