数据结构代码汇总(1)

随着学期的结束,数据结构的课内学习也快要结束了,期末考试也快要来了。
由于实验的考试可以开卷考,但是书上的伪代码有些过于难懂了,所以我打算借着整理复习资料的机会,把数据结构常考的代码用程序语言实现,作为一个模板,方便大家参考,当然,由于每道题之间有些差别,即使本系列文章是用程序语言实现,也不可能符合每道题的需求,只是为了便于大家理解。另外,本系列文章是根据我手上的教材:《数据结构–用C语言描述》(耿国华主编),为了便于大家查找,我尽可能的多写一些注释,并且把此代码在书上的位置标出来。
创作声明:
1.我写这篇文章的目的不是因为觉得这本教材不好,而是为了大家更好的理解,也是我复习的过程,如果我有哪里写的不对或不好欢迎大家评论区批评指正。不要喷我,感谢~
2.既然是程序语言实现,那么编码过程中风格必然是依照我的代码习惯来写,比如我非常不喜欢宏定义,大家根据自己的情况适当修改。
3.由于一些算法比较难,考试不考,所以那些算法不会在本系列文章出现。
4.为了简化算法,一些必要的判断我就不写了,因为考试所考的操作大概率是符合条件的,比如本文章线性表插入操作,考试肯定是插在了允许插入的位置,那么判断插入位置的语句我就不写了,实际生产中请自行加入,以提高程序的鲁棒性。
5.为了减少宏定义,本系列文章的大部分操作均以整型(int)实现,请根据需要替换所需的数据类型。

那么本文先从最简单也是最基础的线性表开始

一、顺序表
1.按内容查找
此算法比较简单,略过不写,详情参考教材41页算法2.1,算法时间复杂度o(n)
2.插入操作,教材42页算法2.2,平均移动元素次数:n/2

typedef struct
{
    int elem[100];
    int last;
}seqlist;

void insert(seqlist *l,int i,int e)
{
    int j;
    for(j=l->last;j>=i-1;j--)
    {
        l->elem[j+1]=l->elem[j];//从后往前移
    }
    l->elem[i-1]=e;//插入新元素
    l->last++;//表长加1
}

3.删除操作,43页2.3,平均移动元素次数:(n-1)/2

int Delete(seqlist *l,int i)
{
    int j;
    int temp=l->elem[i-1];
    for(j=i;j<=l->last;j++)
    {
        l->elem[j-1]=l->elem[j];//从前往后移
    }
    l->last--;//表长减1
    return temp;//课本使用指针返回,我个人更喜欢值返回
}

4.合并运算,45页2.4,书上写的挺清晰的,不再额外写一遍了,时间复杂度:o(LA->last+LB->last)

二、单链表
1.节点定义:

typedef struct node
{
    int data;
    struct node *next;
}node,*linklist;

2.初始化,见课本48页2.5,注意传参传指针的指针
3.头插法建立单链表,48页2.6,注意其输入顺序与逻辑顺序是相反的

void createfromhead(linklist l)
{
    node *s;
    int num;
    while(1)
    {
        scanf("%d",&num);
        if(!num)//输入0结尾
            break;
        s=(node*)malloc(sizeof(node);
        s->data=num;
        s->next=l->next;
        l->next=s;
    }
}

4.尾插法建立单链表,49页2.7

void createfromtail(linklist a)
{
    node *r,*s;
    r=a;
    int n;
    while(1)
    {
        scanf("%d",&n);
        if(!n)//输入0结尾
            break;
        s=(node*)malloc(sizeof(node));
        s->data=n;
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

5.查找,50页2.8,2.9,两个算法放在一起写,时间复杂度,o(n)

void search(linklist a,int pos,int key)//pos是按位置查找的位置,key是按之查找的值,请根据所需操作修改本函数,并且自行添加返回操作
{
    node *p=a->next;
    int i=1,flag=1;
    do
    {
        if(i==pos)//按位置查找的结束条件
        {
            flag=0;
            break;
        }
        if(p->data==key)//按值查找的结束条件
        {
            flag=0;
            break;
        }
        p=p->next;
    }while(p!=a);
    if(flag)
        printf("没找到,略略略")
}

6.求长度,52页2.10,此算法比较简单,本文不再赘述
7.单链表插入,53页2.11,此算法比较简单,只是新增节点+修改指针,注意指针的方向,本文不再赘述
8.删除元素,54页2.12,此算法比较简单,只是修改指针+释放节点,注意指针的方向,本文不再赘述
9.合并55页2.13

linklist merge(linklist a,linklist b)
{
    node *p,*q,*r;
    linklist c;
    c->next=NULL;
    p=a->next;
    q=b->next;
    r=c;
    while(p!=NULL && q!=NULL)
    {
        if(p->data <= q->data)//按顺序合并
        {
            r->next=p;
            r=r->next;
            p=p->next;
        }
        else
        {
            r->next=q;
            r=r->next;
            q=q->next;
        }
        if(p)
           r->next=p;
        else
           r->next=q;
}

三、循环链表
1.建立链表,课本57页
基本算法同建立单链表,只不过最后一步让指针指向头结点,而不再是null了
2.合并算法,58页2.14,此算法比较简单,找到表位指针,修改指针指向即可
四、双向链表
1.节点定义

typedef struct dnode
{
    int data;
    node *prior;
    node *next;
}dnode,*LinkList;

2.插入宇删除操作,60页2.16,2.17,注意指针修改的顺序

五.本章经典例题的实现
一元多项式相加
书上的代码还是挺清楚的,在此我仅仅介绍一下相加函数思路,首先他用两个指针指向第一个节点,把两者相加的结果存储在第一个链表,所以尾指针tail指向了polya,然后开始扫描两个多项式,如果第一个指数小,则tail指针后移(p所指的元素进入和多项式,也就是polya),如果二者相等,则系数相加,如果相加等于0了,那么这个节点就可以删掉了,系数和不等于0,则把和多项式对应的系数改为二者之和,继续扫描下一个,如果第一个指数大,则把第二个加到和多项式中,反复执行,只到有一个多项式扫描结束。后续只需把未扫描的多项式剩余部分加入即可。
不得不说作者的想法确实比我高明,我当时做这道题的思路非常繁琐,下面是我的思路,明显比作者的繁琐多了。

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

typedef struct node
{
    float xishu;
    int zhishu;
    struct node *next;
}node,*linklist;

void initlist(linklist *a)
{
    *a=(node*)malloc(sizeof(node));
    (*a)->next=NULL;
}

void createfromtail(linklist a,int count)
{
    node *r,*s;
    r=a;
    while(count)
    {
        s=(node *)malloc(sizeof(node));
        scanf("%f %d",&s->xishu,&s->zhishu);
        r->next=s;
        r=s;
        count--;
    }
    r->next=NULL;
}

int length(linklist *a)
{
    int i=1;
    node *p=(*a)->next;
    while(p->next!=NULL)
    {
        i++;
        p=p->next;
    }
    return i;
}

void sort(linklist *l)
{
    int tempz,i;
    float tempx;
    node *current=(*l)->next,*nextnode;
    for(i=0;i<length(&(*l))-1;i++)
    {
        nextnode=current;
        do
        {
            nextnode=nextnode->next;
            if(nextnode->zhishu>current->zhishu)
            {
                tempz=current->zhishu;
                current->zhishu=nextnode->zhishu;
                nextnode->zhishu=tempz;

                tempx=current->xishu;
                current->xishu=nextnode->xishu;
                nextnode->xishu=tempx;
            }
        }while(nextnode->next!=NULL);
        current=current->next;
    }
}

void add(linklist a,linklist b)
{
    node *pa=a,*pb=b->next,*temp;
    int flag=1;
    do
    {
        pa=pa->next;
        pb=b->next;
        while(1)
        {
            if(pb->zhishu==pa->zhishu)
            {
                pa->xishu+=pb->xishu;
            }
            if(pb->next==NULL)break;
            pb=pb->next;
        }
    }while(pa->next!=NULL);
    pb=b->next;
    do
    {
        flag=1;
        pa=a;
        do
        {
            pa=pa->next;
            if(pa->zhishu==pb->zhishu)
            {
                flag=0;
                break;
            }
        }while(pa->next!=NULL);
        if(flag)
        {
            temp=(node*)malloc(sizeof(node));
            pa->next=temp;
            temp->xishu=pb->xishu;
            temp->zhishu=pb->zhishu;
            temp->next=NULL;
        }
        pb=pb->next;
    }while(pb!=NULL);
}

void del(linklist *l)
{
    node *p=*l;
    do
    {
        if(p->next->xishu==0)
        {
            p->next=p->next->next;
        }
        else
        {
            p=p->next;
        }
    }while((p->next!=NULL)&&(p!=NULL));
}

int main()
{
    int n1,n2,n3;
    linklist A,B;
    scanf("%d",&n1);
    initlist(&A);
    initlist(&B);
    createfromtail(A,n1);
    scanf("%d",&n2);
    createfromtail(B,n2);
    add(A,B);
    sort(&A);
    del(&A);
    //showlist(A);
    scanf("%d",&n3);
    node *p=A;
    while(n3&&(p->next)!=NULL)
    {
        p=p->next;
        n3--;
    }
    printf("%.1f %d",p->xishu,p->zhishu);
    return 0;
}

这道题和书上略微不同,这道题的多项式是降序排列的,书上是升序排列的,书上相互比较的方法保证了插入的大小顺序,而我没有保证插入顺序,还需要调用一下链表上的冒泡排序,链表上的冒泡排序就是sort函数,大家可以参考一下

这本书前面的代码可读性还是非常高的,所以前面的许多算法我就略过了,但是后面图的算法较为难懂,后面我尽量详细的为大家写一写

本文到此结束,欢迎大家评论区探讨交流。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值