循环链表以及双链表以及线性表习题

1.循环单链表可以从表中的任意一个结点开始遍历整个链表,循环单链表设尾指针,

原因是:若设的是头指针,对表尾操作需要O(n)的时间复杂度,若设的是尾指针r,

r->next即为头指针,对表头与表尾进行操作都只需O(1)的时间复杂度。

int InitCLinkList(LinkList *CL) {
    *CL = (LinkList)malloc(sizeof(LNode));//建立头结点
    if (CL == NULL)//内存不足,分配失败
        return false;
    (*CL)->next = CL;//建立空的循环单链表
    return true;
}
//判断循环单链表是否空
int ISEmpty(LinkList CL) {
    if (CL->next == CL)
        return true;
    else
        return false;
}
//两带头结点循环单链表合并成一个循环单链表
LinkList mergec(LinkList LA, LinkList LB) {
    LNode* p, * q;
    p = LA;
    q = LB;
    while (p->next != LA)
        p = p->next;
    while (q->next != LB)
        q = q->next;
    q->next = LA;
    p->next = LB->next;
    free(LB);
    return LA;
}
//两带头结点循环单链表合并成一个循环单链表,当设置的是尾指针时
LinkList mergec2(LinkList RA, LinkList RB) {
    LNode* p;
    p = RA->next;
    RA->next = RB->next->next;
    free(RB->next);
    RB->next = p;
    return RB;
}

2.双向循环链表的结点结构

 

typedef struct DNode {
    ElemType data;
    struct DNode* prior, * next;
}DNode, * DoubleLink;
int InsertDlink(DoubleLink L,int i,ElemType e) {
    DNode* s, * p;
    int k;
    if (i < 0)
        return false;
    p = L;
    k = 0;
    while (p->next != L && i < k) {
        p = p->next;
        k = k + 1;
    }
    if (p->next == L)
        return false;
    s = (DNode*)malloc(sizeof(DNode));
    if (s)
    {
        s->data = e;
        s->prior = p->prior;
        p->prior->next = s;
        s->next = p;
        p->prior = s;
        return true;
    }
    else
        return false;
}
int delDlink(DoubleLink L, int i, ElemType* e) {
    DNode* p;
    int k;
    p = L;
    k = 0;
    while (p->next != L && k < i) {
        p = p->next;
        k = k + 1;
    }
    if (p->next == L) {
        return false;
    }
    *e = p->data;
    p->prior->next = p->next;
    p->next->prior = p->prior;
    free(p);
    return true;
}

 

//对于带头结点单链表将小于第一个结点的元素放在第一个结点之前,大于第一个结点的元素放在第一个结点之后
void changelist(LinkList L) {
    if (L->next == NULL)
        return false;
    LNode* p1, * pre, * p,*q;
    p1 = L->next;
    pre = p1;
    p = p1->next;
    while (p) {
        q = p->next;
        if (p->data >= p1->data) {
            pre = p;
            p = q;
        }
        else {
            pre->next = p->next;
            p->next = L->next;
            L->next = p;
            p = q;
        }
    }
}
//递增有序单链表,删除值重复的结点
void Delre(LinkList L) {
    LNode* p, *q,*pre;
    pre = L->next;
    p=pre->next;
    while (p != NULL) {
        if (pre->data == p->data) {
            q = pre;
            pre = p;
            p = p->next;
            free(q->next);
        }
        else
        {
            q->next = p;
            pre = p;
            p = p->next;
        }
    }
}
//查找单链表中到数第k个结点,并输出该结点值
//p先移动到第k个结时,q与p同步移动,当遍历完链表时,q所指为到数第k个结点
int Search_k(LinkList list, int k)
{
    LNode* p = list->next, * q = list->next;
    int count = 0;
    while (p != NULL) {
        if (count < k)
            count++;
        else
            q = q->next;
        p = p->next;
    }
    if (count < k)
        return 0;
    else {
        printf("%d", p->data);
        return 1;
    }
}

 

posted @ 2021-09-27 22:06  #Lorraine#  阅读(145)  评论(0)    收藏  举报