单链表(C++实现)

一、实验要求

 (1).尾插法创建单链表,打印创建结果。

(2).头插法创建单链表,打印创建结果。

(3).销毁单链表。

(4).求链表长度。

(5).求单链表中第i个元素(函数),若不存在,报错。

(6).在第i个结点前插入值为x的结点。

(7).链表中查找元素值为x的结点,成功返回结点指针,失败报错。

(8).删除单链表中第i个元素结点。

(9).在一个递增有序的单链表L中插入一个值为x的元素,并保持其递增有序特性。

(10).将单链表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的单链表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。

(11).求两个递增有序单链表L1和L2中的公共元素,放入新的单链表L3中。

(12).删除递增有序单链表中的重复元素,要求时间性能最好。

(13).递增有序单链表L1、L2,不申请新结点,利用原表结点对2表进行合并,并使得合并后成为一个集合,合并后用L1的头结点作为头结点,删除L2的头结点,要求时间性能最好。

二、数据结构设计

typedef  int elementType ;
typedef struct slNode{        //结构体的定义
    elementType data;
    struct slNode * next;
}node,*linkList;

三、代码实现

#ifndef _LINKEDLIST_H_
#define _LINKEDLIST_H_
#include <stdio.h>
#include <stdlib.h>

typedef  int elementType ;

typedef struct slNode{        //结构体的定义
    elementType data;
    struct slNode * next;
}node,*linkList;

//初始化函数
void initList(node ** L)
{
    (*L)->next=NULL;
}
//1.尾插法创建单链表,打印创建结果。
void rearCreatList(node * * L)
{
    elementType x;
    node * u,*r;
    *L=(node *)malloc(sizeof(node));    //创建头结点
    initList(L);
    r = *L;
    printf("按-1结束,请输入链表元素:\n");
    scanf("%d",&x);
    while(x!=-1)
    {
        u=(node *)malloc(sizeof(node));    //创建新结点
        u->data=x;
        u->next=r->next;
        r->next=u;               //将新节点链接表尾
        r=u;
        scanf("%d",&x);
    }
    printf("链表L为:");
    print(L);
}
//2.头插法创建单链表,打印创建结果。
void headCreatList(node * * L)
{
    elementType x;
    node * u;
    *L=(node *)malloc(sizeof(node));    //创建尾结点
    initList(L);
    printf("按-1结束,请输入链表元素:\n");
    scanf("%d",&x);
    while(x!=-1)
    {
        u=(node *)malloc(sizeof(node));    //创建新结点
        u->data=x;
        u->next=(*L)->next;
        (*L)->next=u;                //将新节点链接表头,使之成为首节点
        scanf("%d",&x);
    }
    printf("链表L为:");
    print(L);
}
//打印函数
void print(node * *L)
{
    node *p;
    p=(*L)->next;
    while(p!=NULL)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
}
//3.销毁单链表
void destroyList(node **L)
{
    node *p,*q;
    p=*L;          //初始化时p指向头结点
    while(p!=NULL) //p不为空时执行
    {
        q=p->next; //q变量记录p的下一个节点
        free (p);  //释放p结点
        p=q;       //把q赋值给p
    }
    
}
//4.求链表长度。
int listLen(node **L)
{
    int c=0;   //计数器
    node *p;
    p=(*L)->next;
     while(p!=NULL)
    {
        c++;
        p=p->next;
    }
    return c;
}
//5.求单链表中第i个元素(函数),若不存在,报错。
int getElementList(node **L,elementType * x)
{
     int i;
     node *p;
     p=(*L)->next;
     printf("请输入元素位置:");
     scanf("%d",&i);
     if(i<1 || i>listLen(L))     //判断位置是否出错
     {
         printf("不存在该位置!\n");
         return 0;
     }
     else{
         while(i--)
         {
            p=p->next;
         }
         * x=p->data;
         return 1;
     }

}
//6.在第i个结点前插入值为x的结点。
void insertList(node **L)
{
     int i;
     node *p,*u,*q;   //p为第i-1个结点的指针,u为插入的新节点,q为第i个结点的指针
     elementType x;
     p=*L;
     printf("请输入插入元素位置:");
     scanf("%d",&i);
     i--;
     printf("请输入插入的元素:");
     scanf("%d",&x);
    if(i<0 ||  i>(listLen(L)+1))
    {
        printf("不存在该位置!\n");    //判断位置是否出错
    }
    else{
        while(i--)
         {
            p=p->next;
         }
         u=(node *)malloc(sizeof(node));  //生成插入的节点
         q=p->next;
         u->data=x;
         u->next=q;                       //链接插入的节点
         p->next=u;
         printf("插入的元素后链表为:");
         print(L);
    }
}
//7.链表中查找元素值为x的结点,成功返回结点指针,失败报错。
node * returnP(node **L)
{

    elementType x;
    node * p;
    p=(*L)->next;
    printf("请输入元素:");
    scanf("%d",&x);
    while(p!=NULL&&p->data!=x )
        {
            p=p->next;
        }
    if(p==NULL)
    {
        printf("不存在该元素!\n");    //失败报错
    }
    else{
        printf("元素存在!");
    }
    return p;
}
//8.删除单链表中第i个元素结点。
void deleteList(node **L)
{
     int i;
     node *p,*u,*q;   //p为第i-1个结点的指针,u第i+1个结点的指针,q为第i个结点的指针
     p=*L;
     printf("请输入删除元素位置:");
     scanf("%d",&i);
     i--;
    if(i<0 ||  i>listLen(&*L))
    {
        printf("不存在该位置!\n");    //判断位置是否出错
    }
    else{
         while(i--)
         {
            p=p->next;
         }
         u=p->next;
         q=p->next->next;
         p->next=q;
         free(u);
         printf("删除元素后链表L为:");
         print(L);
    }
}
//9.在一个递增有序的单链表L中插入一个值为x的元素,并保持其递增有序特性。
void insertOrderList(node **L)
{
    node *p,*u;    //u指向插入的新节点
    elementType x;
    p=(*L);
    printf("请输入元素:");
    scanf("%d",&x);
    while(p->next!=NULL&&p->next->data<=x)
    {
            p=p->next;
    }
    u=(node *)malloc(sizeof(node));     //申请新节点
    u->data=x;
    u->next=p->next;
    p->next=u;
    printf("插入元素后链表L为:");
    print(L);
}
//10.将单链表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的单链表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果
void analyzeList(node **L)
{
    node * p;
    node *L1,*L2,*M,*N,*u,*t;
    p=(*L)->next;                      //初始化时p指向头结点L
    L1=(node *)malloc(sizeof(node));   //生成头指针L1
    L2=(node *)malloc(sizeof(node));   //生成头指针L2
    M=L1;                              //初始化时M指向头结点L1
    N=L2;                              //初始化时N指向头结点L2
    initList(&L1);                     //初始化L1
    initList(&L2);                     //初始化L2
    while(p!=NULL)                     //如果链表不为空,继续执行
    {
        if(p->data%2==0)               //如果是偶数,插入链表L1
        {
            u=(node *)malloc(sizeof(node));    //创建新结点
            u->data=p->data;            //采用尾插法,创建链表
            u->next=M->next;
            M->next=u;
            M=u;
        }
        else{                           //如果是奇数,插入链表L2
            t=(node *)malloc(sizeof(node));    //创建新结点
            t->data=p->data;            //采用尾插法,创建链表
            t->next=N->next;
            N->next=t;
            N=t;
        }
        p=p->next;                      //p后移一位
    }
    printf("偶数项L1为:");
    print(&L1);                         //打印链表L1
    printf("奇数项L2为:");
    print(&L2);                         //打印链表L2
    destroyList(&L1);                   //销毁链表L1
    destroyList(&L2);                   //销毁链表L2
}
//11.求两个递增有序单链表L1和L2中的公共元素,放入新的单链表L3中。
void commonList()
{
    node *L1,*L2,*L3;
    node *p,*q,* u,*r;          //p,q分别指向L1,L2,u为L3插入的新节点
    rearCreatList(&L1);
    rearCreatList(&L2);
    L3=(node *)malloc(sizeof(node));
    initList(&L3);
    r =L3;
    printf("链表L1的元素为:");
    print(&L1);
    printf("链表L2的元素为:");
    print(&L2);
    p=L1->next;              //p指向L1的头结点
    q=L2->next;              //q指向L2的头结点
    while(p!=NULL&&q!=NULL)
    {
        if(p->data==q->data)
        {
            u=(node *)malloc(sizeof(node));
            u->data=p->data;
            u->next=r->next;          //用了尾插法
            r->next=u;
            r=u;
            p=p->next;
            q=q->next;
        }
        else if((p->data) > (q->data))
        {
            q=q->next;
        }
        else{
            p=p->next;
        }
    }
    printf("\n");
    printf("链表L3的元素为:");
    print(&L3);
    destroyList(&L1);
    destroyList(&L2);
    destroyList(&L3);
}
//12.删除递增有序单链表中的重复元素,要求时间性能最好。
void deleteReaptElement(node ** L)
{
    node *p,*q;                    //定义两个指针
    p=(*L)->next;                  //初始化时p指向首节点
    q=(*L)->next->next;            //初始化时q指向首节点之后的节点
    while(q!=NULL)
    {
        if(p->data==q->data)
        {
            q=q->next;              //如果p->data==q->data,q后移一位
        }
        else{
            p->next->data=q->data;  //如果不相等,把q->data赋值给p->next->data
            p=p->next;              //p后移一位
        }
    }
    destroyList(&(p->next));        //销毁p->next以后的节点
    p->next=NULL;                   //把p->next->next置为空
    printf("删除重复元素后链表L为:");
    print(& L);                     //输出链表L
}
//13.递增有序单链表L1、L2,不申请新结点,利用原表结点对2表进行合并,并使得合并后成为一个集合,合并后用L1的头结点作为头结点,删除L2的头结点,要求时间性能最好。
void mergeList()
{
    node * L1,* L2;       //定义两个链表L1,L2
    node *p,*q,*u;        //p,q分别指向L1,L2,u指向被删除的节点
    rearCreatList(&L1);   //创建链表L1
    rearCreatList(&L2);   //创建链表L2
    p=L1;                 //初始化时指向头结点L1
    q=L2;                 //初始化时指向头结点L2
    while(p->next!=NULL && q->next!=NULL)
    {
        if(p->next->data==q->next->data)
        {
            u=q->next;       //把要删除的节点指针赋值给u
            q->next=u->next; //连接要删除结点的前后结点
            free(u);         //如果L1,L2有重复元素,删除L2中的重复元素
            p=p->next;       //p向后移一位,q不移
        }
        else if((p->next->data)>(q->next->data))
        {
            q=q->next;       //如果(p->next->data)>(q->next->data),q向后移一位
        }
        else{
            p=p->next;       //如果(p->next->data)<(q->next->data),p向后移一位
        }
    }
    if(p->next!=NULL)        //如果p没有指向尾结点,使它指向尾结点
    {
        while(p->next!=NULL)
        {
            p=p->next;
        }
    }
    p->next=L2->next;         //L1尾结点p连接L2首节点
    free(L2);                 //删除L2头结点
    printf("合并后L1为:");
    print(&L1);
    destroyList(&L1);         //销毁链表
}
#endif // _LINKEDLIST_H_
#include <stdio.h>
#include <stdlib.h>
#include "linkedList.h"

int main()
{
    int len,i=100;
    elementType x;
    node * L;
    while(i!=0)
    {
        printf("******************************************************************************\n");
        printf("按0退出程序并销毁单链表\n");
        printf("按1尾插法创建单链表\n");
        printf("按2头插法创建单链表\n");
        printf("按3求链表长度\n");
        printf("按4求单链表中第i个元素\n");
        printf("按5在第i个结点前插入值为x的结点\n");
        printf("按6查找元素值为x的结点\n");
        printf("按7删除单链表中第i个元素结点\n");
        printf("按8在一个递增有序的单链表L中插入一个值为x的元素,并保持其递增有序特性\n");
        printf("按9将单链表L中的奇数项和偶数项结点分解开\n");
        printf("按10求两个递增有序单链表L1和L2中的公共元素,放入新的单链表L3中\n");
        printf("按11删除递增有序单链表中的重复元素\n");
        printf("按12递增有序单链表L1、L2,不申请新结点,利用原表结点对2表进行合并,并使得合并后成为一个集合,合并后用L1的头结点作为头结点,删除L2的头结点\n");
        printf("*******************************************************************************\n");
        scanf("%d",&i);
        switch(i)
        {
            case 0:
                destroyList(&L);
                return ;
            case 1:
               rearCreatList(&L);
                break;
            case 2:
                headCreatList(&L);
                break;
            case 3:
                len=listLen(&L);
                 printf("链表长度为:%d",len);
                break;
            case 4:
                if(getElementList(&L,&x))
                {
                     printf("第i个元素为:%d\n",x);
                }
                break;
            case 5:
                insertList(&L);
                break;
            case 6:
                returnP(&L);
                break;
            case 7:
                deleteList(&L);
                break;
            case 8:
                insertOrderList(&L);
                break;
            case 9:
                analyzeList(&L);
                break;
            case 10:
                commonList();
                break;
            case 11:
                deleteReaptElement(&* L);
                break;
             case 12:
                mergeList();
                break;
        }
        system("PAUSE");
        system("CLS");
    }
    destroyList(&L);
    return 0;
}

四、实验截图

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值