线性表~单链表~基本操作及扩展操作

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

typedef struct node               //结点类型(名称)
{
    int data;                     //结点的数据域
    struct node *next;            //结点的后继指针
} linknode,*linkp;

/*单链表的使用~函数申明*/
linkp creatList(linkp head);      //建立单链表
void printfList(linkp head);      //打印链表
int lengthList(linkp head);       //求单链表长度
int searchList(linkp head);       //按序号查找表中元素
linkp insertLink(linkp head);     //插入新结点
linkp deleteLink(linkp head);     //删除表中结点
linkp inversionLink(linkp head);  //倒置链表
linkp mergeLink(linkp head,linkp head2);//合并链表

int main()
{
    linkp head,head2,head3;


    head=(linkp)malloc(sizeof(linknode));   //malloc分配内存成功返回的为内存的首地址
    head->next=NULL;
    head=creatList(head);           //建立单链表


    head2=(linkp)malloc(sizeof(linknode));
    head2->next=NULL;
    head2=creatList(head2);         //建立单链表


    head3=(linkp)malloc(sizeof(linknode));
    head3->next=NULL;
    head3=mergeLink(head,head2);
    printfList(head3);              //单链表的顺序合并

    lengthList(head);               //求链表长度

    printfList(head);               //打印链表

    searchList(head);               //按序号查找报表中元素

    head=insertLink(head);          //插入新结点
    printfList(head);

    head=deleteLink(head);          //删除表中结点
    printfList(head);

    head=inversionLink(head);       //单链表的倒置
    printfList(head);
}
//函数定义

/*单链表的基本操作*/

linkp creatList(linkp head)        //建立单链表
{
    int a,i=1;
    linkp p,t;
    head=(linkp)malloc(sizeof(linknode));
    t=head;
    printf("请输入第%d个数据元素:",i);
    scanf("%d",&a);               //输入数据元素
    while(a!=-1)
    {
        p=(linkp)malloc(sizeof(linknode));  //申请新结点
        p->data=a;
        t->next=p;
        t=p;                      //存入数据,将新结点链入表尾
        i++;
        printf("请输入第%d个数据元素:",i);
        scanf("%d",&a);
    }
    t->next=NULL;                 //表尾后继置空,防止野指针
    return head;
}

void printfList(linkp head)       //打印单链表
{
    linkp p=head->next;
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
}

int lengthList(linkp head)        //求单链表长度
{
    linkp p=head->next;
    int num=0;
    while(p)
    {
        num++;
        p=p->next;
    }
    printf("单链表长度为 %d\n",num);
    return num;
}

int searchList(linkp head)       //按序号查找表中元素
{
    int i,j=0;
    linkp p=head;
    printf("请输入需要查找的元素编号:");
    while(~scanf("%d",&i))
    {
        if(i<0)
            printf("输入有误,请重新输入:");
        else break;
    }
    while(p->next&&j<i)
    {
        p=p->next;
        j++;
    }
    if(j==i) printf("需要查找的元素值为%d\n",p->data);
    else  printf("需要查找的元素不存在!!!");
}

linkp insertLink(linkp head)     //插入新结点
{
    int x,n,i=1;
    linkp p,q;
    printf("请输入需要插入结点的位置:");
    while (~scanf("%d",&x))
    {
        if(x<1||x>lengthList(head)+1)
            printf("输入有误,请重新输入:");
        else
        {
            printf("请输入要插入的数据元素:");
            scanf("%d",&n);
            break;
        }
    }
    p=head;
    while(i!=x)
    {
        p=p->next;
        i++;
    }
    q=(linkp)malloc(sizeof(linknode));
    q->data=n;
    q->next=p->next;
    p->next=q;
    return head;
}

linkp deleteLink(linkp head)   //删除单链表结点
{
    int n,i=1;
    linkp p,q;
    p=head;
    printf("请输入需要删除结点的位置:");
    while(~scanf("%d",&n))
    {
       if(n<1||n>lengthList(head))
       {
           printf("输入有误,请重新输入:");
       }
       else break;
    }
    while(i!=n)
    {
        p=p->next;
        i++;
    }
    q=p->next;
    p->next=q->next;
    return head;
}

/*单链表的扩展运算*/

linkp inversionLink(linkp head)      //倒置单链表
{
    linkp p,q;
    p=head->next;
    head->next=NULL;
    while(p)
    {
        q=p;
        p=p->next;                   //q=p,对指针q进行操作同时也会影响到指针p
        q->next=head->next;
        head->next=q;
    }
    return head;
}

linkp mergeLink(linkp head,linkp head2)   //单链表的顺序合并
{
    linkp p1,p2,head3;
    if(head->next->data < head2->next->data)  //找出两个链表中第一个结点较小的结点,head3记录较小结点的头结点
    {
        head3=head;
        p1=head->next;
        p2=head2->next;
    }
    else
    {
        head3=head2;
        p2=head2->next;
        p1=head->next;
    }
    linkp r=head3;
    while(p1&&p2)                             //在两个链表中遍历比较,将值较小的结点链接到r结点后
    {
        if(p1->data <= p2->data)
        {
            r->next=p1;
            r=p1;
            p1=p1->next;
        }
        else
        {
            r->next=p2;
            r=p2;
            p2=p2->next;
        }
    }                                        //将p1或p2剩余的结点链到r之后,完成整个合并的过程
    if(p1)
        r->next=p1;
    if(p2)
        r->next=p2;
    return head3;
}

猜你喜欢

转载自blog.csdn.net/mycsdn_xm/article/details/80672827