链表C实现

//线性表的链式存储:单链表
typedef struct LNode {//结点类型定义
    ElemType data;//数据域
    struct LNode* next;//指针域
}LNode,*LinkList;
//不管带不带头结点,头指针都始终指向链表的第一个结点,而头结点是带头结点的链表中的第一个结点,结点内通常不存储信息
//带头结点的单链表
int InitLink(LinkList* L) {
    *L = (LinkList)malloc(sizeof(LNode));
    if (L == NULL)
        return false;
    (*L)->next = NULL;
    return true;
}
//不带头结点
int InitList(LinkList* L) {
    L = NULL;
    return true;
}
//采用头插法建立单链表时,读入数据的顺序与生成的链表中的元素的顺序是相反的
//头插法创建单链表
//每个结点插入的时间是O(1),设单链表长度为n,则总时间复杂度是O(n)
LinkList HeadInsert(LinkList L) {
    LNode* s;
    int x;
    InitLink(&L);
    scanf_s("%d", &x);
    while (x != 9999) {
        s = (LNode*)malloc(sizeof(LNode));
        s->data = x;
        s->next=L->next;
        L->next = s;
        scanf_s("%d", &x);
    }
    return L;
}
//尾插法
LinkList TailInsert(LinkList L) {
    int x;
    L = (LinkList)malloc(sizeof(LNode));
    L->next = NULL;
    LNode* s, * r = L;
    scanf("%d", &x);
    while (x != 9999) {
        s = (LNode*)malloc(sizeof(LNode));
        s->data = x;
        r->next = s;
        r = s;
        scanf_s("%d", &x);
    }
    r->next = NULL;
    return L;
}
//按序号查找结点值
LNode* GetElem(LinkList L, int i) {
    int j = 1;
    LNode *p = L->next;
    if (i == 0)
        return L;
    if (i < 1)
        return NULL;
    while (p && j < i) {
        p = p->next;
        j++;
    }
    return p;
}
//
LNode* GetElemX(LinkList L, int i) {
    if (i < 0)
        return NULL;
    LNode* p;
    int j = 0;
    p = L;//头结点是第0个结点
    while (p != NULL && j <i) {
        p = p->next;
        j++;
    }
    return p;
}
//按值查找表结点
LNode* LocateElem(LinkList L, ElemType e) {
    LNode *p;
    p = L->next;
    while (p != NULL && p->data != e)
        p = p->next;
    return p;
}
//求带头结点的单链表的长度
int ListLength(LinkList L) {
    LNode *p;
    p = L->next;
    int j = 0;//用来存放单链表的长度
    while (p != NULL) {
        p = p->next;
        j++;
    }
    return j;//j为求得的单链表长度
}
//单链表插入
void InsertList(LinkList L, int i, ElemType e) {
    //带头结点,在第i个位置插入元素e
    LNode* pre, * s;
    int k;
    if (i <= 0)
        return false;
    pre = L;
    k = 0;
    while (pre != NULL && k < i-1) {
        pre = pre->next;
        k = k + 1;
    }
    if (pre == NULL) {
        printf("插入位置不合法");
        return false;
    }
    s = (LNode*)malloc(sizeof(LNode));
    s->data = e;
    s->next = pre->next;
    pre->next = s;
    return true;
}
//单链表删除,带头结点,删除第i个元素
int DelList(LinkList L, int i, ElemType *x) {
    LNode* pre, * r;
    int k;
    pre = L;
    k = 0;
    while (pre->next != NULL && k < i - 1) {
        pre = pre->next;
        k = k + 1;
    }
    if (pre->next == NULL) {
        return false;
    }
    r = pre->next;
    pre->next = r->next;
    *x = r->data;
    free(r);
    return true;    
}
LinkList MergeList(LinkList A, LinkList B) {
    LNode* pa, * pb,*r;
    LinkList LC;
    pa = A->next;
    pb = B->next;
    LC = A;
    LC->next = NULL;
    r = LC;
    while (pa != NULL && pb != NULL) {
        if (pa->data <= pb->data) {
            r->next = pa;
            r = pa;
            pa = pa->next;
        }
        else {
            r->next = pb;
            r = pb;
            pb = pb->next;
        }
    }
    if (pa)
        r->next = pa;
    else
        r->next = pb;
    free(B);
    free(LC);
}
//递归删除所有x
void DelX(LinkList L, ElemType x) {
    LNode *p;
    if (L == NULL)
        return;
    if (L->data== x) {
        p = L;
        L = L->next;
        free(p);
        DelX(L, x);
    }
    else
    {
        DelX(L->next, x);
    }

}

 

//删除所有值为x的结点并释放
void Delxfree(LinkList L, ElemType x) {
    LNode *p,*s,*pre=L;
    p = L->next;
    while (p != NULL) {
        if (p->data == x)
        {
            s = p;//s指向该结点
            p = p->next;
            pre->next = p;
            free(s);
        }
        else {//否则,p和pre同步移动
            pre = p;
            p = p->next;
        }
    }
}
//反向输出各个结点的值
void PrintR(LinkList L) {//递归
    if (L->next != NULL)
        PrintR(L->next);
    if (L != NULL)
        print(L->data);
}
void R_ignore_Head(LinkList L) {
    if (L != NULL)
        PrintR(L->next);
}
void delMin(LinkList *L) {//先找再删
    LNode* pre=L, * p = pre->next;
    LNode* minp=p, * minpre=pre;
    while (p != NULL) {
        if (p->data < minp->data) {
            minp = p;
            minpre = pre;
        }
        pre = p;
        p = p->next;
    }
    minpre->next = minp->next;
    free(minp);
    return L;
}
//就地逆置
LinkList Reverse2(LinkList L) {
    LNode* pre, * p, * r=p->next;
    p->next = NULL;//处理第一个结点
    while (r != NULL) {//r为空,则说明p为最后一个结点
        pre = p;//依次继续遍历
        r = r->next;
        p = r;
        p->next = pre;//指针反转
    }
    L->next = p;//处理第一个结点
    return L;
}
//找公共结点,先遍历两个链表得到他们的长度,
//并求出两个长度之差,长链表先遍历长度差个结点,然后同步遍历,直到找到相同的结点
int commonNode(LinkList L1, LinkList L2) {
    int len1 = Length(L1), len2 = Length(L2),dist;
    LinkList longlist, shortlist;
    if (len1 > len2) {
        longlist = L1->next;
        shortlist = L2->next;
        dist = len1 - len2;
    }
    else {
        longlist = L2->next;
        shortlist = L1->next;
        dist = len2 - len1;
    }
    while (dist--) 
        longlist = longlist->next;
    while (longlist != NULL) {
        if (longlist == shortlist)
            return longlist;
        else {
            longlist = longlist->next;
            shortlist = shortlist->next;
        }

    }
    return NULL;
}
//递增单链表中去掉重复值
void Delre(LinkList L) {
    LNode* p = L->next, * q;
    if (p == NULL)
        return;
    while (p != NULL) {
        q = p->next;
        if (p->data == q->data) {
            p->next = q->next;
            free(q);
        }
        else
            p = p->next;
    }
}
//两个按元素递增次序排列的单链表,合并成一个按元素值递减次序排列
//利用原来的结点存放合并的单链表
void MergeL(LinkList La, LinkList Lb) {
    LNode* r, * pa = La->next, * pb = Lb->next;
    La->next = NULL;//链表初始化为空
    while (pa && pb)//当链表均不为空时,循环
        if (pa->data <= pb->data) {
            r = pa->next;
            pa->next = La->next;
            La->next = pa;
            pa = r;
        }
        else
        {
            r = pb->next;
            pb->next = La->next;
            La->next = pb;
            pb = r;
        }
    if (pa)
        pb = pa;
    while (pb) {
        r = pb->next;
        pb->next = La->next;
        La->next = pb;
        pb = r;
    }
    free(Lb);
}

 

//A、B两单链表递增有序,带头结点,从A和B中产生单链表C,但不破坏A、B的结点
//比较A、B中的元素,值小的往后移,相等时,创立新节点,赋其值,使用尾插法,直到有一个遍历到链尾即可
void GetCommon(LinkList A, LinkList B) {
    LNode* p = A->next, * q = B->next, * r, * s;
    LinkList C = (LinkList)malloc(sizeof(LNode));
    r = C;
    while (p != NULL && q != NULL) {
        if (p->data < q->data)
            p = p->next;
        else if (p->data > q->data)
            q = q->next;
        else {
            s = (LNode*)malloc(sizeof(LNode));
            s->data = p->data;
            r->next = s;
            r = s;
            p = p->next;
            q = q->next;
        }
    }
    r->next = NULL;//置C尾结点指针为空
}
//对于绝对值相同的两个元素,保留先出现的,删除后出现的,用辅助数组
typedef struct node {
    int data;
    struct node *link;
}NODE;
typedef NODE *PNODE;
void func(PNODE h, int n) {
    PNODE p = h, r;
    int* q, m;
    q = (int*)malloc(sizeof(int) * (n + 1));//申请n+1个辅助空间
    for (int i = 0; i < n + 1; i++)//数组元素初值置0
        *(q + i) = 0;
    while (p->link != NULL) {
        m = p->link->data > 0 ? p->link->data : -p->link->data;
            if (*(q + m) == 0) {//判断该结点的data是否已经出现过
                *(q + m) = 1;//首次出现
                p = p->link;//保留
            }
            else {
                r = p->link;
                p->link = r->link;
                free(r);
            }
    }
    free(q);        
}

 

posted @ 2021-09-24 22:11  #Lorraine#  阅读(43)  评论(0)    收藏  举报