数据结构学习---单链表

单链表非常经典,还是面试中常考的内容。

相对于有序表,有不同的地方,可以通过修改之前的有序表来编写单链表。

有以下特征:

  1.有数据域和有指针域
  2.插入和删除比较方便
  3.长度没有限制
  4.查找不方便
  5.结点的存储地址可以不连续

 1 #ifndef _STRUCTLINKLIST_H_
 2 #define _STRUCTLINKLIST_H_
 3 enum{
 4     ERROR = -1,
 5     OK,
 6     FALSE = 0,
 7     TRUE
 8 };
 9 typedef int Status;
10 typedef int ElemType;
11 typedef struct LNode{
12     ElemType data;
13     struct LNode * next;
14 }LinkList, * pLinkList;
15 
16 #endif

Elemtype是为了可移植性, *pLinkList是为了方便以后定义指针,之后定义指针都是直接pLinkList 。。。这样写的

#include<stdio.h>
#include"StructLinkList.h"
#include<stdlib.h>
/*point at Head Node*/
pLinkList InitHeadNode()
{
    pLinkList pHead;
    pHead = (pLinkList)malloc(sizeof(LinkList));
    pHead->next = NULL;
    return pHead;
}

初始化头结点。

/*************************************************************************
    > File Name: Show.c
    > Author: aaron
    > Mail: 60360329@163.com
    > Created Time: Wed 15 Mar 2017 03:35:21 PM CST
 ************************************************************************/

#include<stdio.h>
#include"StructLinkList.h"

void show(pLinkList pLink)
{
    pLinkList pTmp = pLink->next;
    if (NULL == pLink|| NULL == pTmp)
        return;
    int i;
    for(i = 0 ; i < 10 ;i++)
        printf("%d\t",i+1);
    printf("\n");
    while(pTmp)
    {
        printf("%d\t",pTmp->data);
        pTmp = pTmp->next;
    }
    printf("\n");
}

显示链表中的内容,定义的元素类型是整形,打印数字。通过创建指针,移动遍历整个链表,到null时停止。

/*************************************************************************
    > File Name: IsEmpty.c
    > Author: aaron
    > Mail: 60360329@163.com
    > Created Time: Wed 15 Mar 2017 11:10:01 AM CST
 ************************************************************************/

#include<stdio.h>
#include"StructLinkList.h"

Status IsEmpty(pLinkList pLink)
{
    if(pLink->next)
        return TRUE;
    else
        return FALSE;
}

判断空

/*************************************************************************
    > File Name: Insert_BY_Head.c
    > Author: aaron
    > Mail: 60360329@163.com
    > Created Time: Wed 15 Mar 2017 01:37:11 PM CST
 ************************************************************************/

#include<stdio.h>
#include"StructLinkList.h"
#include<stdlib.h>
Status InsertByHead(pLinkList pHead,ElemType INdata)
{
    pLinkList pTmp = (pLinkList)malloc(sizeof(LinkList));
    pTmp->data = INdata;
    pTmp->next = pHead->next;
    pHead->next = pTmp;
    return OK;
}

头插法。新节点保存头结点指向后的指针,再由头结点指向新结点。

/*************************************************************************
    > File Name: Delete_by_Head.c
    > Author: aaron
    > Mail: 60360329@163.com
    > Created Time: Wed 15 Mar 2017 02:42:26 PM CST
 ************************************************************************/

#include<stdio.h>
#include"StructLinkList.h"
#include<stdlib.h>
ElemType DeleteByHead(pLinkList pLink)
{
    pLinkList pTmp = pLink->next;
    ElemType OUTdata = pTmp->data;
    pLink->next = pTmp->next;
    free(pTmp);
    return OUTdata;
}

不要忘了free。

 1 #include<stdio.h>
 2 #include"StructLinkList.h"
 3 
 4 int LenghtOfLinkList(pLinkList pLink)
 5 {
 6     int count = 0;
 7     pLinkList pTmp = pLink->next;
 8     while(pTmp)
 9     {
10         count++;
11         pTmp = pTmp->next;
12     }
13     return count;
14 }
lenght

求长度也是遍历链表

/*************************************************************************
    > File Name: DestroyLinkList.c
    > Author: aaron
    > Mail: 60360329@163.com
    > Created Time: Wed 15 Mar 2017 10:13:30 AM CST
 ************************************************************************/

#include<stdio.h>
#include"StructLinkList.h"
#include<stdlib.h>
Status DestroyLinkList(pLinkList pLink)
{
    if (NULL == pLink)
        return ERROR;
    pLinkList pTmp;
    while(pLink)
    {
        pTmp = pLink->next;
        free(pLink);
        pLink = pTmp;
    }
    return OK;
}
Status CleanLinkList(pLinkList pLink)
{
    pLinkList pTmp1,pTmp2;
    pTmp1 = pLink->next;
    while(pTmp1)
    {
        pTmp2 = pTmp1->next;
        free(pTmp1);
        pTmp1 = pTmp2;
    }
    //DestroyLinkList(pLink->next);     the another way
    return OK;
}

销毁和清除函数。差不多一样写在一起了

/*************************************************************************
    > File Name: SreachItem.c
    > Author: aaron
    > Mail: 60360329@163.com
    > Created Time: Wed 15 Mar 2017 02:58:34 PM CST
 ************************************************************************/

#include<stdio.h>
#include"StructLinkList.h"

pLinkList SreachItem(pLinkList pLink,ElemType INdata)
{
    pLinkList pTmp = pLink;
    while(INdata != pTmp->data)
    {
        pTmp = pTmp->next;
        if (NULL == pTmp)
        {
            printf("there is not the data!\n");
            return NULL;
        }
    }
    return pTmp;
}

查找,同样也是遍历不过要知道找不到怎么处理。

 1 /*************************************************************************
 2     > File Name: UpdateItem.c
 3     > Author: aaron
 4     > Mail: 60360329@163.com
 5     > Created Time: Wed 15 Mar 2017 03:07:03 PM CST
 6  ************************************************************************/
 7 
 8 #include<stdio.h>
 9 #include"StructLinkList.h"
10 
11 void UpdateItem(pLinkList pLink,int location,ElemType INdata)
12 {
13     if (NULL == pLink)
14         return;
15     if (location < 0)
16     {
17         printf("location is so small\n");
18         return;
19     }
20     pLinkList pTmp = pLink;
21     while(location--)
22     {
23         if(NULL == pTmp->next->next)
24         {
25             printf("location is so big\n");
26             return;
27         }
28         pTmp = pTmp->next;
29     }
30     pTmp->data = INdata;
31 }
update

这个是更新内容原理和查找差不多。

/*************************************************************************
    > File Name: DelItem.c
    > Author: aaron
    > Mail: 60360329@163.com
    > Created Time: Wed 15 Mar 2017 09:39:27 PM CST
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include"StructLinkList.h"

Status  DelItem(pLinkList pLink,int location,ElemType * OUTdata)
{
    if (NULL == pLink)
    {
        exit(-1);
    }
    pLinkList pTmp = pLink;
    pLinkList qTmp = pLink->next;
    while(--location)
    {
        pTmp = pTmp->next;
        if (NULL == pTmp)
        {
            printf("the number is big!\n");
            return ERROR;
        }
        qTmp = qTmp->next;
    }
    if (NULL == qTmp)
    {
        printf("the number is big!\n");
        return ERROR;
    }
    pTmp->next = qTmp->next;
    *OUTdata = qTmp->data;
    free(qTmp);
}

删除要防止越界。

用两个指针记录录要删除位置之前的节点还有当前删除结点。

删除是要ptmp的next指针指向下下个结点。

释放qtmp

 1 /*************************************************************************
 2     > File Name: InsertItemForLink.c
 3     > Author: aaron
 4     > Mail: 60360329@163.com
 5     > Created Time: Wed 15 Mar 2017 11:43:05 AM CST
 6  ************************************************************************/
 7 
 8 #include<stdio.h>
 9 #include<stdlib.h>
10 #include"StructLinkList.h"
11 
12 void InsertItemForLink(pLinkList pLink,int location,ElemType INdata)
13 {
14     if (NULL == pLink)
15         return;
16     pLinkList pTmp = (pLinkList)malloc(sizeof(LinkList));
17     pTmp->data = INdata;
18     pLinkList qTmp = pLink;
19     while(--location)
20         qTmp = qTmp->next;
21     pTmp->next = qTmp->next;
22     qTmp->next = pTmp;
23 }

这里没有下防止越界的语句但是和上面的类似。

 1 /*************************************************************************
 2     > File Name: reversLinkList.c
 3     > Author: aaron
 4     > Mail: 60360329@163.com
 5     > Created Time: Wed 15 Mar 2017 10:26:12 PM CST
 6  ************************************************************************/
 7 
 8 #include<stdio.h>
 9 #include<stdlib.h>
10 #include"StructLinkList.h"
11 pLinkList reversLinkList(pLinkList pLink)
12 {
13     if (NULL == pLink)
14         exit(ERROR);
15     pLinkList rem = pLink;
16     pLink = pLink->next;
17     pLinkList NextTmp = NULL;
18     pLinkList PreTmp = NULL;
19     while(NULL != pLink)
20     {
21         NextTmp = pLink->next;
22         pLink->next = PreTmp;
23         PreTmp = pLink;
24         pLink = NextTmp;
25     }
26     rem->next = PreTmp;
27     printf("\n");
28     return rem;
29 }

倒置链表,这个是除开头结点的倒置,记录下处理之前的位置pretmp,还有之后要处理的next

单链表操作要保存next为先,这里也一样,然后为了倒置,把当前链表的next指针指向pre(之前遍历到的结点)那么,我们就实现了把指针反向。

把当前结点存在pre,向后移动结点。当然plink是实实在的地址,是把地址在不停的赋值,作用在抽象的链表上,不像之前定义的ptmp是不会改变链表的

所以改变链表就要动plink。最后把之前保存好的头结点指向pre。因为循环结束条件是plink为null,那么pre里就存放了已经倒置了链表。

————————若有错误请大神指出,谢谢!!

转载于:https://www.cnblogs.com/mrAAron/p/6559080.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值