单链表的建立及其功能实验报告

实验名称 单链表的建立及其功能

  • 实验内容、基本原理
  1. 实验内容

建立单链表,输入数据元素,对创建的单链表进行插入、删除数据元素、排序(根据字符对应的ASCII码进行由小到大)及退出功能。

2.基本原理

①创建

创立头结点,并令其指针指向NULL。构建函数,每加入一个新的数据元素,就建一个新的结点,令该结点的指针指向头结点指针所指位置,头结点指针指向该结点位置(头插法),结合循环语句,当输入为零的时候结束单链表的创建,这样就可以实现创建任意长度的单链表(在一定的范围内)。

插入

构建函数,确定插入位置(由用户输入),结合循环语句和判断语句,如果位置超出单链表的长度,显示输出错误并返回循环,重新输入要插入的位置。创立新的结点并赋值,定义两个指针,借助循环使得一个指向定位好的结点的前一个结点,另一个指向创立的新结点。令新结点的指针指向定位好的结点的下一个结点,令定位好的结点的指针指向新的结点。

删除

构建函数,确定删除位置(由用户输入)。定义两个指针,借助循环使一个指针指向目标结点,另一个指针指向其前置结点,令第二个指针所指结点的指针指向第一个指针所指结点的后置结点,释放第一个指针所指的结点。

​​​​​​​④排序

此方法类似于冒泡排序法。构建函数,定义两个指针p,q,及一个整形指标变量t,为t赋值为1使得循环得以开始。t的作用:如果后续操作比较大小时有交换操作,则再进行外循环一次,直到后续比较大小无交换操作,即数据完成按从小到大顺序的排序操作。在外循环中,每次循环都使得q指向头结点,p指向第一个结点,t赋值为0以便排好顺序后停止循环。内循环里,从第一个结点开始,比较相邻的数据的大小,如需交换,则再次定义一个指针tmp,使其指向p指针指向的结点的指针指向的结点,此时三个指针分别指向三个相邻的结点。令q指向的结点的指针指向tmp指向的结点,p指向的结点的指针指向tmp指向的结点的指针,tmp指向的结点的指针指向p指向的结点,交换操作完成。为t赋值为1使得可以再进行一次外循环。内循环里,无论是否需要交换,都要将p、q指针移向下一个结点,以便后面的数据的大小判断。整个函数进行的操作:对单链表中数据进行多次扫描,第一次扫描会将含有最大数据的结点放在单链表最后,第二次扫描会将含有第二大数据的结点放在倒数第二的位置,以此类推。此算法和冒泡法不同的是,此算法在顺序正确的时候会直接退出循环,而冒泡法必须要进行特定步骤的循环次数;此算法在后面的扫描中,也会比较已经拍好顺序的数据,而冒泡法不会。

​​​​​​​⑤退出

为循环设定条件,当输入指定字符(如‘q’或‘Q’)时退出循环。

3.实验步骤和结果

步骤

参考教材中的相应的内容(P25),首先建立单链表,其次编写主函数,引用创建的几个函数,结合循环语句和分支语句,实现相对应的功能。

结果

  • 实验中出现的问题及解决方法
  1. 问题:程序较为复杂棘手,难以编写。
  2. 解决方法:与同学交流互助,完成程序。
  • 实验总结及体会

该实验较为复杂,对于刚接触数据结构的我来说,可能有点复杂,需要初次建立单链表,还需要编写数个函数来实现单链表的多个功能。如此复杂的实验需要我们提前预习,上课认真听讲,课后好好巩固复习才能顺利完成。

  • 附录

#include<stdio.h>
#include<malloc.h>
typedef char ElemType;
typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;
void fun(LinkList head){
    LNode *p=head->next,*q=head;
    int t=1;
    while(t){
        p=head->next;
        q=head;
        t=0;
        while(p&&p->next){
            if(p->data>p->next->data){
                LNode *tmp=p->next;
                q->next=tmp;
                p->next=tmp->next;
                tmp->next=p;
                t=1;
            }
            q=p;
            p=p->next;
        }
    }
}
int ListInsert_L(LinkList head,int i,ElemType e){
    LinkList p=head;
    LinkList s;
    int j;
    for(j=1;j<i;j++){
        if(p) p=p->next;
        else break;
    }
    if(!p||i<1){
        printf("error!!请输入正确的i!!\n");
        return 0;
    }
    s=(LinkList)malloc(sizeof(LNode));
    s->data=e;
    s->next=p->next;
    p->next=s;
    return 1;
}
LinkList CreateList_L(LinkList head){
    ElemType temp;
    LinkList p;
    printf("请输入结点值(输入0结束):");
    fflush(stdin);
    scanf("%c",&temp);
    while(temp!='0'){
        if(('A'<=temp&&temp<='Z')||('a'<=temp&&temp<='z')){
            p=(LinkList)malloc(sizeof(LNode));
            p->data=temp;
            p->next=head->next;
            head->next=p;
        }
        printf("请输入结点值(输入0结束):");
        fflush(stdin);
        scanf("%c",&temp);
    }
    return head;
}
int ListDel_L(LinkList head,int i){
    LinkList p,tmp;
    int j;
    p=head->next;
    tmp=head;
    for(j=1;j<i;j++){
        if(p){
            p=p->next;
            tmp=tmp->next;
        }
        else break;
    }
    if(!p||i<1){
        printf("error!!请输入正确的i!!\n");
        return 0;
    }
    tmp->next=p->next;
    free(p);
    return 1;
}
void ListPint_L(LinkList head){
    LinkList p;
    int i=0;
    p=head->next;
    while(p!=NULL){
        i++;
        printf("%d个元素是:",i);
        printf("%c\n",p->data);
        p=p->next;
    }
}
void main(){
    int i;
    char cmd,e;
    LinkList head;
    head=(LinkList)malloc(sizeof(LNode));
    head->next=NULL;
    CreateList_L(head);
    ListPint_L(head);
    do{
        printf("i,I...插入\n");
        printf("d,D...删除\n");
        printf("q,Q...退出\n");
        printf("o,O...排序\n");
        do{
            fflush(stdin);
            scanf("%c",&cmd);
        }while((cmd!='d')&&(cmd!='D')&&(cmd!='q')&&(cmd!='Q')&&(cmd!='i')&&(cmd!='I')&&(cmd!='o')&&(cmd!='O'));
        switch(cmd){
        case 'i':
        case 'I':
            printf("请输入你要插入的数据:");
            fflush(stdin);
            scanf("%c",&e);
            printf("请输入你要插入的位置:");
            scanf("%d",&i);
            ListInsert_L(head,i,e);
            ListPint_L(head);
            break;
        case 'd':
        case 'D':
            printf("请输入你要删除的元素的位置:");
            fflush(stdin);
            scanf("%d",&i);
            ListDel_L(head,i);
            ListPint_L(head);
            break;
        case 'o':
        case 'O':
            fun(head);
            ListPint_L(head);
            break;
        }
    }while((cmd!='q')&&(cmd!='Q'));
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值