数据结构之链表的实现以及各种应用

#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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值