单链表的逆置和中间结点的查找

  顺序表的单链表存储:

        1 单链表的建立,建立单链表有头插法和尾插法两种,前者的链表元素与初始化顺序相反,后者则相同,可根据需要选择,下面的程序采用的是尾部插入建立,是为了方便测试逆置和中间结点的查找。

        2 单链表的删除和插入: 首先,删除结点,一般会找到一个结点,比如是p,然后是删除后面结点还是前面结点,如果是删除后面的结点,则直接删除后替换就 可以了;如果是删除前面结点,由于单链表的性质,所以可以将p中结点内容复制到要删除的结点数据域中,然后就与后删一样了。插入也分为前插与后插,后插比较简单,前插也可改为后插,此时将两个结点的数据互换即可。

       3 单链表的逆置和中间结点的查找,写了个代码测试了下,linux下gcc测试可用。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int ElemType;

typedef struct _LinkNode{
    ElemType data;
    struct _LinkNode *next;
}LinkNode;

//创建带头结点的单链表,尾插法建立
LinkNode* CreateLinkList(LinkNode *L)
{
    ElemType data;
    LinkNode *r = NULL, *p = NULL;

    L = (LinkNode*)malloc(sizeof(LinkNode));
    if(NULL ==  L)
        return NULL;
    memset(L, 0 , sizeof(LinkNode));

    r = L;
    scanf("%d",&data);
    while(data != 0){
        p = (LinkNode*)malloc(sizeof(LinkNode));
        //malloc出错处理
        p->data = data;
        p->next = NULL;
        r->next = p;
        r = p;
        scanf("%d",&data);
    }

    return L;
}

//打印带头结点的单链表中的所有value
void PrintLink(LinkNode *L)
{
    LinkNode *p = L->next;

    while(p != NULL){
        printf("%d ", p->data);
        p = p->next;
    }

    printf("\n");

    return ;    
}

//带头结点的单链表逆置
void LinkReverse(LinkNode *L)
{
    if(L->next == NULL)
        return;

    LinkNode *p = NULL, *q = NULL;
    p = L->next;
    q = p->next;

    while(q){
        p->next = q->next;
        q->next = L->next;
        L->next = q;

        q = p->next;
    }

    return ;    
}


//使用大小指针查找未知长度单链表的中间结点,L为头结点
//奇数个结点返回中间结点,偶数个则返回靠前一个的结点
LinkNode* LinkSearchMid(LinkNode *L)
{
    if(L->next == NULL)
        return NULL;

    LinkNode *p, *q;

    p = L->next;
    q = L->next;

    while(p->next != NULL){
        p = p->next->next;
        if(!p){
            break;    
        }
        q = q->next;
    }

    return q;
}


int main()
{
    LinkNode *L = NULL;

    L = CreateLinkList(L);
    PrintLink(L);
    
    LinkNode *p = NULL;
    p = LinkSearchMid(L);
    if(p)
        printf("mid = %d\n",p->data);
    else
        printf("Link is empty!\n");

    LinkReverse(L);
    PrintLink(L);
    return 0;    
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值