链表——单向链表

链表

解决了:长度固定,插入删除麻烦的问题

1)逻辑结构:线性结构

2)存储结构:链式存储结构

3)操作:增删改查

单向链表

结构体:

struct   node_t

{

int data;//数据域

struct   node_t * next;//存放下一个节点的地址

}

头文件:

"[code=C/C++]"

#ifndef _LINKLIST_H_
#define _LINKLIST_H_

typedef int datatype;
typedef struct node_t
{
	datatype data;//数据域
	struct node_t *next;//指针域,指向自身结构体的指针
}link_node_t,*link_list_t;

//1.创建一个空的单向链表(有头单向链表)
link_node_t *CreateEpLinkList();
//2.向单向链表的指定位置插入数据
//p保存链表的头指针 post 插入的位置 data插入的数据
int InsertIntoPostLinkList(link_node_t *p,int post, datatype data);
//3.遍历单向链表
void ShowLinkList(link_node_t *p);
//4.求单向链表长度的函数
int LengthLinkList(link_node_t *p);
//5.删除单向链表中指定位置的数据 post 代表的是删除的位置
int DeletePostLinkList(link_node_t *p, int post);
//6.判断单向链表是否为空 1代表空 0代表非空
int IsEpLinkList(link_node_t *p);
//7.修改指定位置的数据 post 被修改的位置 data修改成的数据
int ChangePostLinkList(link_node_t *p, int post, datatype data);
//8.查找指定数据出现的位置 data被查找的数据 //search 查找
int SearchDataLinkList(link_node_t *p, datatype data);
//9.删除单向链表中出现的指定数据,data代表将单向链表中出现的所有data数据删除
int DeleteDataLinkList(link_node_t *p, datatype data);
//10.转置链表
void ReverseLinkList(link_node_t *p);
//11.清空单向链表
void ClearLinkList(link_node_t *p);
#endif



"[/code"

代码:

"[code=C]"

#include"link_list.h"
link_node_t *CreateEpLinkList()
{
    link_node_t *p=(link_node_t *)malloc(sizeof(link_node_t));
    if(p==NULL)
    {
        perror("CreateEpLinkList err");
        return NULL;
    }
    p->next=NULL;
    return p;
}
int LengthLinkList(link_node_t *p)
{
    int len=0;
    while(p->next!=NULL)
    {
        p=p->next;
        len++;
    }
    return len;
}
int InsertIntoPostLinkList(link_node_t *p,int post, datatype data)
{
    
  if(post<0||post>LengthLinkList(p))
    {
        perror("InsertIntoPostLinkList err");
        return -1;
    }
   for(int i=0;i<post;i++)
    {
            p=p->next;
            
    }
    link_node_t *pnew=(link_node_t *)malloc(sizeof(link_node_t));
    if(pnew==NULL)
    {
        perror("pnew err");
        return -1;
    }
    pnew->data=data;
    pnew->next=NULL;

    pnew->next=p->next;//插入的链接下一个的地址
    p->next=pnew;   //将上一个的链接地址写入插入的地址

    return 0;  
}
int IsEpLinkList(link_node_t *p)
{
 return p->next==NULL;
}
int DeletePostLinkList(link_node_t *p, int post)
{
     if(post<0||IsEpLinkList(p)||post>=LengthLinkList(p))
    {
        perror("DeletePostLinkList err");
        return -1;
    }
    for(int i=0;i<post;i++)
    {
            p=p->next;   
    }
    link_node_t *pdel=p->next;
    p->next=pdel->next;
    free(pdel);
    pdel=NULL;
    return 0;    
}
void ShowLinkList(link_node_t *p)
{
    while(p->next!=NULL)
    {
        p=p->next;
        printf("%d ",p->data);
    }
    printf("\n");
}
int ChangePostLinkList(link_node_t *p, int post, datatype data)
{
     if(post<0||IsEpLinkList(p)||post>=LengthLinkList(p))
    {
        perror("ChangePostLinkList err");
        return -1;
    }
    for(int i=0;i<post;i++)
    {
            p=p->next;   
    }
   p->data=data;
   return 0;
}
int SearchDataLinkList(link_node_t *p, datatype data)
{      int i=0;
       while(p->next!=NULL)
    {  
        p=p->next;
       if(p->data==data)
       {
       printf("%d ",i);
      
       }
        i++;
    }
    printf("\n ");
}
 int DeleteDataLinkList(link_node_t *p, datatype data)
{      
     link_node_t *pdel=NULL;
     link_node_t *q=p->next;//探路小兵
     
    while(q!=NULL)//循环便利
    { 
    if(q->data==data)//等于data的全部进入if
    {
        pdel=q;
        p->next=pdel->next;//这个的地址pdel+1的地址赋值给p->next
        free(pdel);
        pdel=NULL;
        q=p->next;//q向着下一个目标位置前进
    }
    else
    {
        p=p->next;
        q=p->next;
    }
    }
    return 0;    
}     

void ClearLinkList(link_node_t *p)//清屏
{
    link_node_t *pdel=p->next;
    while(p->next!=NULL)
    {
        pdel=p->next;
        p->next=pdel->next;
        free(pdel);
        pdel=NULL;
    }
}
void ReverseLinkList(link_node_t *p)
{
   link_node_t *tep=NULL;//定义暂时的空指针
   link_node_t *q=p->next;//断头前,保留第一个节点的地址

   p->next=NULL;//段头

   while(q!=NULL)
{
    tep=q->next;//tep等于q下一个地址
    q->next=p->next;//将无头链接的节点等于断头链接的p下一个节点
    p->next=q;//让断头链接p的下一个地址等于q的地址
    q=tep;//将q重新等于tep保存的下一个地址
}
    return p;
}
"[code=C/"

主函数:

"[code=C]"
#include"link_list.h"
int main(int argc, char const *argv[])
{
link_node_t *p=CreateEpLinkList();
InsertIntoPostLinkList(p,0, 10);
InsertIntoPostLinkList(p,1, 20);
InsertIntoPostLinkList(p,2, 30);
InsertIntoPostLinkList(p,3, 40);
InsertIntoPostLinkList(p,4, 50);
InsertIntoPostLinkList(p,5, 50);
InsertIntoPostLinkList(p,6, 50);
InsertIntoPostLinkList(p,7, 50);
ShowLinkList(p);
DeletePostLinkList(p,3);
ShowLinkList(p);
ChangePostLinkList(p, 2,100);
ShowLinkList(p);
SearchDataLinkList(p, 50);
ReverseLinkList(p);
 ShowLinkList(p);
DeleteDataLinkList(p, 50);
ShowLinkList(p);
ClearLinkList(p);
ShowLinkList(p);
return 0;
}

"[code=C/"

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值