菜鸟之路--线性表__链表实现

//好久没发博客了,今天来水上一发,以后要勤劳耕作!!!!!!!!!!!!

/*
    文件link.h
    链表的头文件,定义了链表的存储结构,以及操作方法
*/
#ifndef LINK_L
#define LINk_L 0

#define OK 1
#define FALSE 0
#define ERROR -1
typedef int Status;
//typedef int ElemType;
typedef struct LNode{
    ElemType  data;
    struct LNode * next;
}Link,* Position;
typedef struct{
    Link * head;
    Link * tail;
} LinkList;

Status MakeNode(Link **p,ElemType e);
void FreeNode(Link **p);
Status ListEmpty(LinkList *l);
Status InitList(LinkList **l);
Status DestroyList(LinkList *l);
Status ClearList(LinkList *l);
Status InsFirst(LinkList *l,Link *h,Link *s);
Status DelFirst(LinkList *l,Link *h,Link *q);
Status Append(LinkList *l,Link *s);
Status Remove(LinkList *l,Link *q);
Status InsBefore(LinkList *l,Link *q,Link *s);
Status InsAfter(LinkList *l,Link *q,Link *s);
Status SetCurElem(Link *q,ElemType e);
ElemType GetCurElem(Link *q);
Status ListEmpty(LinkList *l);
int ListLength(LinkList *l);
Position GetHead(LinkList *l);
Position GetLast(LinkList *l);
Position PriorPos(LinkList *l,Link * p);
Position NextPos(LinkList *l,Link * p);
Status LocatePos(LinkList *l,int i,Link *p);
Position LocateElem(LinkList *l,ElemType e,Status (* compare)(ElemType,ElemType));
Status LocateTraverse(LinkList *l,Status (* visit)());
Status MergeList_L(LinkList  *la,LinkList  *lb,LinkList  *lc,int (* compare)(ElemType,ElemType));
Status ListSort(LinkList *l,int (* compare)(ElemType,ElemType));
#endif // LINK_L

/*
       文件link.cpp
       包含了方法的实现,以及新增的辅助方法
*/
#include<stdio.h>
#include<stdlib.h>
#include "Link.h"

Status MakeNode(Link **p,ElemType e){
    *p = (Link *)malloc(sizeof(Link));
    if(p != NULL){
        (*p)->data = e;
        (*p)->next = NULL;
        return OK;
    }
    return FALSE;
}
void FreeNode(Link **p){
    free(*p);
    *p= NULL;
}

Status InitList(LinkList **l){
    *l = (LinkList *)malloc(sizeof(LinkList));
    Link *tnode;
    MakeNode(&tnode,0);
    if(*l != NULL){
        (*l)->head = tnode;
        (*l)->tail = tnode;
        return OK;
    }
    return FALSE;
}
Status DestroyList(LinkList *l){
    free(l);
    return OK;
}
Status ClearList(LinkList *l){
    if(l != NULL){
        if(l->head->next){
            Link * temp = l->head;
            l->head = l->head->next;
            FreeNode(&temp);
        }
        l->tail = l->head;
        return OK;
    }
    return FALSE;
}
//在链表的第一个位置插入节点,h指向头结点
Status InsFirst(LinkList *l,Link *h,Link *s){
    s->next = h->next;
    h->next = s;
    return OK;
}
//在删除链表中第一个节点并以q返回,h为头结点指针
Status DelFirst(LinkList *l,Link *h,Link *q){
    q = h->next;
    h->next = h->next->next;
    return OK;
}
//再链表尾部插入节点
Status Append(LinkList *l,Link *s){
    if(l){
        l->tail->next = s;
        Link *temp = l->head;
        while(temp->next){
            temp= temp->next;
        }
        l->tail =temp;
        return OK;
    }
    return ERROR;
}
//在链表尾部删除节点
Status Remove(LinkList *l,Link *q){
    Link * temp = PriorPos(l,l->tail);
    temp->next = NULL;
    q = l->tail;
    l->tail = temp;
    return OK;
}
//在q所指向的节点前面插入节点
Status InsBefore(LinkList *l,Link *q,Link *s){
    Link * ptemp = PriorPos(l,q);
    ptemp->next = s;
    s->next = q;
    return OK;
}
//在q所指向的节点后面插入节点
Status InsAfter(LinkList *l,Link *q,Link *s){
    s->next = q->next;
    q->next = s;
    if(q == l->tail){
        l->tail = s;
    }
    return OK;
}
//设置q所指向节点的值
Status SetCurElem(Link *q,ElemType e){
    q->data = e;
    return OK;
}
//获取q所指向节点的值
ElemType GetCurElem(Link *q){
    return q->data;
}
//判断链表长度是否为空
Status ListEmpty(LinkList *l){
    if(l->head->next==NULL){
        return OK;
    }
    return FALSE;
}
//计算链表的长度
int ListLength(LinkList *l){
   int length=0;
   Link * p= l->head->next;
   while(p){
        length++;
        p=p->next;
   }
    return length;
}
//获取链表的头指针
Position GetHead(LinkList *l){
    return l->head;
}
//获取链表的尾指针
Position GetLast(LinkList *l){
    return l->tail;
}
//获取p所指的元素的前一个元素
Position PriorPos(LinkList *l,Link * p){
    Link * temp = l->head;
    while(temp->next != p){
        temp = temp->next;
    }
    return temp;
}
//获取p元素所指的后一个元素
Position NextPos(LinkList *l,Link * p){
    return p->next;
}
//查找链表中第i个元素并以p返回
Status LocatePos(LinkList *l,int i,Link *p){
    p=NULL;
    if(i>0 && i<ListLength(l)){
        int count = 0 ;
        p = l->head;
        while(count != i){
            p = p->next;
            count++;
        }
        return OK;

    }
    return ERROR;
}
//查找与e相等的节点并返回该节点
Position LocateElem(LinkList *l,ElemType e,Status (* compare)(ElemType,ElemType)){
    Link *temp = l->head->next;
    while((* compare)(temp->data,e) != 0  && temp){
        temp = temp->next;
    }
    return temp;
}
//检查是否有错误节点
Status LocateTraverse(LinkList *l,Status (* visit)()){
    Link * temp = l->head->next;
    while(temp){
        if((* visit)() == ERROR){
            return FALSE;
        }
        temp = temp->next;
    }
    return OK;
}
//合并俩个链表并以lc新链表返回,la,lb会被破坏
Status MergeList_L(LinkList * la,LinkList  *lb,LinkList * lc,int (* compare)(ElemType,ElemType)){
    Link *ha,*hb,*pa,*pb;
    ha  = la->head;
    hb  = lb->head;
    pa  = NextPos(la,ha);
    pb  = NextPos(lb,hb);
    while(pa && pb){
        if((*compare)(pa->data,pb->data) == 1){  //pa.data >pb.data
            DelFirst(lb,hb,pb); Append(lc,pb); pb = NextPos(lb,hb);
        }else if((*compare)(pa->data,pb->data) == 0){
            DelFirst(la,ha,pa); DelFirst(lb,hb,pb);Append(lc,pa); pa = NextPos(la,ha);pb = NextPos(lb,hb);
        }else{
            DelFirst(la,ha,pa); Append(lc,pa); pa = NextPos(la,ha);
        }
    }
    if(pa) Append(lc,pa); else Append(lc,pb);
    FreeNode(&ha); FreeNode(&hb);
    return OK;
}
//打印链表信息
Status List_Print(LinkList * l){
    Link *p = l->head->next;
    printf("长度=%d\n",ListLength(l));
    while(p){
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
    return OK;
}
Status ListSort(LinkList *l,int (*compare)(ElemType,ElemType)){
    Link * ptemp1 = l->head->next;
    Link * ptemp2 = ptemp1->next;
    //冒泡排序
    while(ptemp1!=l->tail){
        ptemp2 = ptemp1->next;
        while(ptemp2){
            if((*compare)(ptemp1->data,ptemp2->data) == 1){
                printf("%d--%d ",ptemp1->data,ptemp2->data);
                ElemType ntemp = ptemp1->data;
                ptemp1->data = ptemp2->data;
                ptemp2->data = ntemp;
            }
            ptemp2 = ptemp2->next;
        }
        ptemp1 = ptemp1->next;
    }
    return OK;

}
//合并两个链表,不破坏lb的结构,最终合并到la表中
Status MergeList(LinkList *la,LinkList *lb,int (* compare)(ElemType,ElemType)){
    Link *pa,*pb;
    pa = la->head->next;
    pb = lb->head->next;
    while(pa && pb){
        if((*compare)(pa->data,pb->data) == 1){
            Link * temp;
            MakeNode(&temp,pb->data);
            //printf("%x ",temp);
            InsBefore(la,pa,temp);
            pb=NextPos(lb,pb);
           // printf("%d--%d ",pa->data,pb->data);
        }
        else if((*compare)(pa->data,pb->data) == -1){
            pa= NextPos(la,pa);
        }else{
            pb=NextPos(lb,pb);
        }
    }
    if(pb) Append(la,pb);
    return OK;
}

int compare(ElemType a,ElemType b){
    if(a>b){
        return 1;
    }else if(a==b){
        return 0;
    }else{
        return -1;
    }
}
int main()
{
     Link *temp;
     int i,m;
     LinkList * la,*lb,*lc;
     InitList(&la);
     InitList(&lb);
     InitList(&lc);
     for(i=0;i<5;i++){
        scanf("%d",&m);
        MakeNode(&temp,m);
        Append(la,temp);
     }
     List_Print(la);
     ListSort(la,compare);
     //Remove(la,temp);
     //printf("你删除的元素是:%d\n",temp->data);
     List_Print(la);
     for(i=4;i>0;i--){
        MakeNode(&temp,i*3);
        Append(lb,temp);
     }
     List_Print(lb);
     MergeList(la,lb,compare);
     List_Print(la);
     ListSort(la,compare);
     List_Print(la);
     List_Print(lb);
     MergeList_L(la,lb,lc,compare);
     List_Print(lc);
     ClearList(la);
     DestroyList(la);
     ClearList(lb);
     DestroyList(lb);
     ClearList(lc);
     DestroyList(lc);
     return 0;
}
//1 8 6 4 7


时间: 2024-10-24 09:54:48

菜鸟之路--线性表__链表实现的相关文章

菜鸟之路--线性表__顺序存储

</pre><pre name="code" class="cpp"> #include <stdio.h> #include <stdlib.h> //链表的定义以及基本操作 typedef void List; typedef void ListNode; //创建一个空链表,并返回 List * List_Create(int capacity); //将链表清空 void List_Clear(List * l

菜鸟之路--线性表__链式存储

</pre><pre name="code" class="cpp">#include <stdio.h> #include <stdlib.h> //链表的定义 typedef void List; typedef void ListNode; //链式链表的相关定义 typedef struct _tag_linklist SqList; typedef struct _tag_linkNode SqListNod

菜鸟之路--线性表__多项式操作(多项式加减乘)

/* <span style="font-size:18px;">代码里的使用的链表请见<a target=_blank href="http://blog.csdn.net/u013303425/article/details/41320861"> http://blog.csdn.net/u013303425/article/details/41320861</a></span> */ #include<st

[考研系列之数据结构]线性表之链表

1.链表分类 通过线性表概述,我们知道了链表这样一种数据结构,它又分成三类,分别是 单向链表 循环链表 双向链表 单向链表 单向链表的指针域只有一个指向下一个节点的指针,需要注意几点: 1.头指针--指向第一个节点 2.最后一个结点的指针指向NULL 3.头结点--在链表的第一个结点之前附设一个结点,它的数据域为空 所以,我们看到:  单向链表为空的<=>链表有且只有一个头结点<=>头结点的指针指向NULL 循环链表 循环链表和单向链表最大的不同就是:最后一个结点的指针不再指向NU

C语言 严蔚敏数据结构 线性表之链表实现

博主最近在考成都大学皇家计算机科学与技术专业,复习专业课数据结构,正好学习到线性结构中的线性表用链表这种存储结构来实现. 首先,数据结构包括1.数据的操作2.逻辑结构3.存储结构(数据结构三要素. 直接上代码,现阶段代码实现功能有:链表初始化.遍历.增.删.返回链表长度,后续功能陆续发布.其中肯定有很多问题,希望各位码哥留言. Linklist* InitList(int i)//i为链表大小 { Linklist *head; head = (Linklist*)malloc(sizeof(L

第二章:3.线性表---静态链表的表示和实现

前言: 由于一些高级程序设计语言中,并没有 "指针" 类型,因此上一节中用指针来描述的单链表不能被实现,这时候我们就会使用另一种形式链表:静态链表. 目录: 1.线性表的链式表示和实现 1.1线性链表 单链表(指针型线性链表) 静态链表 1.2循环链表 1.3双向链表 正文: 线性表的静态单链表存储结构: #define MAXSIZE 100; //链表的最大长度 typedef   struct{ ElemType  data; int  cur; }component, SLin

再回首,数据结构——线性表、链表上的常见算法

最近在复习数据结构,顺便看看大一的时候写的代码,看完之后比当初有了更加深刻的体会. 希望这些能提供给初学者一些参考. //1.编写算法实现线性表就地逆置的操作 void InverseList (SeqList l) { for (i = 0; i <= (l.length-1)/2; i++) { l.elem[i] <-> l.elem[l.length-1-i]; } } //2.从顺序表中删除自第i个元素开始的k个元素 void DeleteList(SeqList l, int

JAVA实现具有迭代器的线性表(单链表)

一,迭代器的基本知识: 1,为什么要用迭代器?(迭代:即对每一个元素进行一次“问候”) 比如说,我们定义了一个ADT(抽象数据类型),作为ADT的一种实现,如单链表.而单链表的基本操作中,大部分需要用到依次遍历单链表中的每一个元素.一般而言,我们就是用for循环来实现遍历,这样,当你新增一个对单链表的操作并需要使用遍历时,你就得重新写一个for循环而实现遍历.那么,为什么不将迭代(遍历)作为一种基本的ADT操作(基本的ADT操作如:新增一个元素.删除一个元素)呢?于是,迭代器就出场了. 2,鉴于

线性表—双链表

1.基础知识 a.双链表结点的结构:其由前序元素地址,数据域,后继元素地址组成. b.双链表结点的连接方法:先声明该结点,可以在内部也可以利用其特性来表明前序结点和后继结点是什么,之后同时还需要说明"其前序结点的后继地址为该结点"和"其后继结点的前序地址为该结点.(本质:双向) 2.循环双链表的实现 线性表接口LList package com.clarck.datastructure.dlinked; /*** 线性表接口LList,描述线性表抽象数据类型,泛型参数T表示数