【数据结构】含头结点的单链表

  • 单链表结构体
  • 头插法构建单链表
  • 尾插法构建单链表
  • 遍历链表
  • 直接合并两个链表
  • 合并有序链表
  • 向单链表中确定位置插入一个元素
  • 主函数调用

目录


各部分实现

单链表结构体

typedef struct tagNode
{
    int data;//数据域
    struct tagNode *next;//指针域,指向下一个元素
}Node,*LinkList;/*LinkList为结构指针类型*/

头插法构建单链表:

L是带头结点的空链表头指针,n是要输入到单链表中的元素个数。L->next始终指向单链表的第一个元素,初始是其指向空。采用头插法,需要创建一个新的结点存储要插入的元素,再将L->next指向的结点赋给s->next,最后将L->next指向新插入的结点s即完成了一次头插法插入。

void CreateHeadList(LinkList L,int n)//头插法
{
    LinkList s;
    while(n--)
    {
        s=(LinkList)malloc(sizeof(Node));/*创建新结点*/
        scanf("%d",&s->data);
        s->next=L->next;/*将新结点的指针域指向现在的头结点指向的结点,实现头插*/
        L->next=s;
    }
}

尾插法构建单链表

L是带头结点的空链表头指针,n是要输入到单链表中的元素个数。实现尾插法需要定义一个结构体指针p始终指向链表的最后一个元素,当链表中没用元素时指向头结点。在每一次插入时创建一个新的结点存储要插入的新元素。使p->next指向这个新创建的结点就完成了尾插法,最后再使指针p指向新的最后一个结点。

void CreateTailList(LinkList L,int n)//尾插法
{
    LinkList p,s;
    p=L;/*初始时指针p指向头结点*/
    while(n--)
    {
        s=(LinkList)malloc(sizeof(Node));
        scanf("%d",&s->data);
        p->next=s,p=s;/*实现尾插*/
    }
    p->next=NULL;/*最后使尾结点的指针域指向空*/
}

遍历链表

从头指针的下一个结点开始遍历单链表,直至下以结点为空。

void ListTraverse(LinkList L)//遍历链表
{
    LinkList p=L->next;/*定义一个结构体指针,指向要遍历的结点,开始时
    指向头结点后的第一个结点*/
    while(p)/*当指针非空时遍历*/
    {
        printf("%d ",p->data);
        p=p->next;/*寻找下一结点*/
    }
    printf("\n");
}

直接合并两个链表

两个单链表L、O,首先找到链表L的最后一个结点,使这个结点的指针域指向链表O的头结点后的第一个结点,就完成了合并。

void ListContact1(LinkList L,LinkList O)
{
    LinkList p=L;
    while(p->next)
    {
        p=p->next;
    }/*找最后一个结点*/
    p->next=O->next;
}

合并有序链表

两个用单链表的有序线性表的合并的方法是顺序表合并的推广,采用尾插法向合并后的链表插入新元素。

void ListContact2(LinkList L,LinkList O,LinkList H)
{
    LinkList l,o,h,s;
    l=L->next;
    o=O->next;
    h=H;/*结构体指针h始终指向最后一个结点*/
    while(l&&o)/*当l或者o指向空时,说明一个链表已经遍历完,循环停止*/
    {
        s=(LinkList)malloc(sizeof(Node));/*创建新结点*/
        s->next=NULL;
        if(l->data<o->data)
        {
            s->data=l->data;
            l=l->next;
        }
        else
        {
            s->data=o->data;
            o=o->next;
        }
        h->next=s;/*尾插法插入新结点*/
        h=s;
    }
    while(l)/*继续遍历插入未遍历完的链表*/
    {
        s=(LinkList)malloc(sizeof(Node));
        s->next=NULL;
        s->data=l->data;
        h->next=s;
        h=s;
        l=l->next;
    }
    while(o)
    {
        s=(LinkList)malloc(sizeof(Node));
        s->next=NULL;
        s->data=o->data;
        h->next=s;
        h=s;
        o=o->next;
    }
}

向单链表中确定位置插入一个元素

void ListInsert(LinkList L,int i,int e)
{
    LinkList p=L,s;
    while(p&&i>1)
    {
        p=p->next;
        i--;
    }
    s=(LinkList)malloc(sizeof(Node));
    s->data=e;
    s->next=p->next;
    p->next=s;
}

主函数调用

int main()
{
    int n,m,i,e;
    LinkList L,O,H;
    L=(LinkList)malloc(sizeof(Node));
    L->next=NULL;/*初始化一个单链表*/
    O=(LinkList)malloc(sizeof(Node));
    O->next=NULL;
    H=(LinkList)malloc(sizeof(Node));
    H->next=NULL;
    printf("输入四个数字,第一个代表第一个链表的长度,第二个代表第二个链表的长度,第三个数代表要插入的位置,第四个数代表要插入的元素:");
    scanf("%d%d%d%d",&n,&m,&i,&e);//n代表L的长度,m代表O的长度,i代表要插入的位置,e代表要插入的元素
    printf("建立第一个链表,按从大到小输入:");
    CreateHeadList(L,n);//头插法
    ListTraverse(L);
    printf("建立第二个链表,按从小到大输入:");
    CreateTailList(O,m);//尾插法
    ListTraverse(O);
    ListContact2(L,O,H);
    ListTraverse(H);
    ListContact1(L,O);
    ListTraverse(L);
    ListInsert(H,i,e);
    ListTraverse(H);
    return 0;
}

全部代码

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

typedef struct tagNode
{
    int data;
    struct tagNode *next;
}Node,*LinkList;


void CreateHeadList(LinkList L,int n)//头插法
{
    LinkList s;
    while(n--)
    {
        s=(LinkList)malloc(sizeof(Node));
        scanf("%d",&s->data);
        s->next=L->next;
        L->next=s;
    }
}

void CreateTailList(LinkList L,int n)//尾插法
{
    LinkList p,s;
    p=L;
    while(n--)
    {
        s=(LinkList)malloc(sizeof(Node));
        scanf("%d",&s->data);
        p->next=s,p=s;
    }
    p->next=NULL;
}

void ListTraverse(LinkList L)//遍历链表
{
    LinkList p=L->next;
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
}

void ListContact1(LinkList L,LinkList O)
{
    LinkList p=L;
    while(p->next)
    {
        p=p->next;
    }
    p->next=O->next;
}
void ListContact2(LinkList L,LinkList O,LinkList H)
{
    LinkList l,o,h,s;
    l=L->next;
    o=O->next;
    h=H;
    while(l&&o)
    {
        s=(LinkList)malloc(sizeof(Node));
        s->next=NULL;
        if(l->data<o->data)
        {
            s->data=l->data;
            l=l->next;
        }
        else
        {
            s->data=o->data;
            o=o->next;
        }
        h->next=s;
        h=s;
    }
    while(l)
    {
        s=(LinkList)malloc(sizeof(Node));
        s->next=NULL;
        s->data=l->data;
        h->next=s;
        h=s;
        l=l->next;
    }
    while(o)
    {
        s=(LinkList)malloc(sizeof(Node));
        s->next=NULL;
        s->data=o->data;
        h->next=s;
        h=s;
        o=o->next;
    }
}

void ListInsert(LinkList L,int i,int e)
{
    LinkList p=L,s;
    while(p&&i>1)
    {
        p=p->next;
        i--;
    }
    s=(LinkList)malloc(sizeof(Node));
    s->data=e;
    s->next=p->next;
    p->next=s;
}

int main()
{
    int n,m,i,e;
    LinkList L,O,H;
    L=(LinkList)malloc(sizeof(Node));
    L->next=NULL;
    O=(LinkList)malloc(sizeof(Node));
    O->next=NULL;
    H=(LinkList)malloc(sizeof(Node));
    H->next=NULL;
    printf("输入四个数字,第一个代表第一个链表的长度,第二个代表第二个链表的长度,第三个数代表要插入的位置,第四个数代表要插入的元素:");
    scanf("%d%d%d%d",&n,&m,&i,&e);//n代表L的长度,m代表O的长度,i代表要插入的位置,e代表要插入的元素
    printf("建立第一个链表,按从大到小输入:");
    CreateHeadList(L,n);//头插法
    ListTraverse(L);
    printf("建立第二个链表,按从小到大输入:");
    CreateTailList(O,m);//尾插法
    ListTraverse(O);
    ListContact2(L,O,H);
    ListTraverse(H);
    ListContact1(L,O);
    ListTraverse(L);
    ListInsert(H,i,e);
    ListTraverse(H);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值