菜鳥之路--線性表__鏈表實現

//好久沒發博客了,今天來水上一發,以後要勤勞耕作!!!!!!!!!!!!
//在使用指針的時候,要注意指針的維護。。。。。
 /*
    文件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(LinkList *l,Link **p){
    if(*p == l->tail){
       l->tail = PriorPos(l,*p);
    }
    l->tail->next=NULL;
    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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章