1. 程式人生 > >資料結構之連結串列的實現以及各種應用

資料結構之連結串列的實現以及各種應用

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>            //the max and the min.
typedef struct LNode{
    int data;
    struct LNode  *next;
}LNode;

//初始化一個連結串列
LNode* initLinkList(LNode *L)
{
    L =(LNode*)malloc(sizeof(LNode));
    L -> next =  NULL;
    return L;

}
int listLength(LNode *L){

    int length = 0;
    LNode *p = L->next;
    while(p!=NULL){
        length++;
        p=p->next;
    }
    //printf("\r\n長度是:%d\r\n",length);
    return length;
}
//-----Important ----
void DestoryList(LNode *&L){

    LNode *q;
    //重要 防止斷鏈 遍歷L
    while(L->next!=NULL){
        //q存L
        q=L->next;
        free(L);
        //更新當前頭結點
        L=q;
    }
}
//單個數據 頭插法 相反順序
void insertLinkListByLNode(LNode *&L,int x){
    LNode *s,*r,*q;
    //新插入元素
    s = (LNode*)malloc(sizeof(LNode));
    s->data = x;
    //讓r等於頭結點
    r=L;
    q=r->next;
    r->next = s;
    s->next = q;
}
//陣列輸入 頭插法 相反順序
void insertLinkListByLNode(LNode *&L,int a[],int n){
    LNode *s,*p,*q;
    int i;
    for(i=0;i<n;i++){
        //新插入元素
        s = (LNode*)malloc(sizeof(LNode));
        s->data = a[i];
        //讓r等於頭結點
        s->next = L->next;
        L->next = s;
    }

}
//單個數據-尾插法 - 是按照輸入順序的
void insertByRear(LNode *&L,int x){
    LNode *s,*r;
    r=L;
    //找到尾
    //只有頭結點
    if(L->next == NULL){
        s = (LNode*)malloc(sizeof(LNode));
        s->data = x;
        r ->next = s;
        s->next = NULL;
        return;
    }
    //已經有插入的元素 找到尾結點在哪//為什麼只能遍歷r 不能遍歷L? 
    while(r->next!=NULL){
        r = r->next;
    }
    //找到當前尾結點在哪
    s = (LNode*)malloc(sizeof(LNode));
    s->data = x;
    r->next = s;
    s->next = NULL;//----->很關鍵
}
//陣列-尾插法 - 是按照輸入順序的
void insertByArrayByRear(LNode *&L,int a[],int n){
    int i;
    LNode *s,*r;
    r = L;//r等於尾
    for(i=0;i<10;i++){
        s = (LNode*)malloc(sizeof(LNode));
        s->data = a[i];
        r ->next = s;
        r = r->next; 
    }
    r->next = NULL;
}
//按順序加入
void insertByorder(LNode *&L,int x){
    LNode *s,*p,*pre_p;//pre_p 前屈 要知道插入的前屈
    pre_p = L;
    p=L->next;
    s = (LNode*)malloc(sizeof(LNode));
    s->data = x;
    //開始為空
    if(L->next == NULL){
        L->next = s;
        s->next = NULL;
        return;
    }
    //找到插入的位置
    while(x>p->data){
        //這個if非常的容易的忽略掉
        if(p->next==NULL) {
            p->next = s;
            return;
        }
        pre_p = pre_p->next;
        p = p->next;
    }
    //p為插入位置
    s ->next = p;
    pre_p ->next = s;
}

//刪除某個值
void DeleteByNum(LNode *&L,int x){
    if(L->next==NULL){
        printf("連結串列為空!不能刪除");
        return;
    }
    LNode *d;
    LNode *p = L->next;
    LNode *pre_p = L;
    while(p!=NULL){
        if(p->data==x){
            d = p;
            p = p->next;
            pre_p->next = p;
            free(d);
        }
        pre_p = pre_p->next;
        p=p->next;
    }
}
//刪除某個位置
void DeleteByPos(LNode *&L,int pos){
     printf("len = %d",listLength(L));
    //位置合法性判斷
    if(pos<0||pos>listLength(L)){
        printf("位置有錯誤,不能刪除!\r\n");
        return;
    }
    //找到插入位置的前一個和後一個指標位置
    LNode *pre_p,*p,*q;
    pre_p = L;
    p = pre_p->next;
    //找插入的位置
    int i=0;printf("i=%d\r\n",i);
    while(i<pos){
        pre_p = pre_p->next;
        p=p->next;
        i++;
    }
    pre_p->next = p->next;
    q = p;
//  e = p->data;
    p=p->next;
    free(q);
}

//排序冒泡
void Lsort(LNode *&L)//整體思想用的氣泡排序思想
{
    int i,j,t;
    LNode *p,*q;//tail代表連結串列每一次排序後的未排序連結串列的最後一個節點
    if(L->next==NULL)     return;
    //
    for(i=0,p=L->next;i<listLength(L)-1;i++,p=p->next){
        for(j=i+1,q = p->next;j<listLength(L);j++,q=q->next)
        {
            if(p->data > q->data)//比較p節點和p->next節點的data大小
            {
                t=p->data;
                p->data=q->data;
                q->data=t;
            }
        }
    }
}
//開闢新的空間,合併兩個連結串列
void Merge_TwoOrdered_List(LNode *A,LNode *B,LNode *&C){
    LNode *p = A->next;
    LNode *q = B->next;
    LNode *s = C;
    while(p&&q){
        if(p->data<=q->data){
            s->next = p;
            s = s->next;
            p=p->next;
        }
        else{
            s->next = q;
            s = s->next;
            q = q->next;
        }   
    }
    if(p==NULL){
        s->next = q;
    }
    if(q==NULL){
        s->next = p;
    }
}
//連結串列的逆轉
void reverse(LNode *L){
    if(L->next==NULL||L->next->next=NULL) return;
    LNode *p;
    LNode *newNode = NULL;
    while(p->next!=NULL){
        LNode *temp = p->next;
        p->next

    }

}
void print(LNode *L){
    LNode *p = L->next;
    if(p==NULL){
        printf("空連結串列!\r\n");
        return;
    }
    while(p!=NULL)
    {
        printf("%d ",p->data);
        p = p->next;
    }
}

void structTest()
{
    LNode *L,*A,*B,*C;
    L = initLinkList(L);
    A = initLinkList(A);
    B = initLinkList(B);
    C = initLinkList(C);
    //單個插入
/*  insertLinkListByF(L,5);
    insertLinkListByF(L,5);
    insertLinkListByF(L,1);
    insertLinkListByF(L,3);
    insertLinkListByF(L,9);
    print(L);*/

    insertByRear(L,0);
    insertByRear(L,1);
    insertByRear(L,8);
    insertByRear(L,3);
    insertByRear(L,4);
    insertByRear(L,5);

    print(L);
    printf("\r\n");
    Lsort(L);
    print(L);
    /*insertByRear(A,1);
    insertByRear(A,4);
    insertByRear(A,8);
    insertByRear(A,9);
    insertByRear(A,100);
    insertByRear(B,2);
    insertByRear(B,4);

    insertByRear(B,5);
    insertByRear(B,100);
    Merge_TwoOrdered_List(A,B,C);
      *///陣列插入
    /*int i,a[100];
    for(i=0;i<10;i++){
        scanf("%d",&a[i]);
    }
    insertByArrayByRear(L,a,10);
    */
/*  int i,a[100];
    for(i=0;i<10;i++){
        scanf("%d",&a[i]);
    }
    insertLinkListByLNode(L,a,10);
    */
/*  insertByorder(L,10);
    insertByorder(L,18);
    insertByorder(L,7);
    insertByorder(L,17);
    insertByorder(L,5);
    insertByorder(L,6);
*/
//  DestoryList(L);

    //insertLinkListByR(L,2);
    //print(L);
    //DeleteByNum(L,15);
//  printf("\r\ndelete\r\n");
//  DeleteByPos(L,8);
//  print(C);
} //Of structTest.

void main()
{
structTest();

} //of main.