循环链表操作(链表带头节点)

#ifndef CIRCULARLIST_H
#define CIRCULARLIST_H

#include 
#include 
#include 
#include 

typedef int ElemType;

// 循环链表节点
typedef struct CircularNode{
    ElemType data;
    struct CircularNode *next;
}*CircularList;

// 返回一个动态分配的新节点,该节点尾部指向头部(头结点不用于存放数据)
CircularList NewCircularListNode()
{
    CircularList list = (CircularList)malloc(sizeof(struct CircularNode));
    if (!list)
        return NULL;
    memset(list, 0, sizeof(struct CircularNode));
    list->next = list;
    return list;
}


void CircularListInfo(CircularList list)
{
    CircularList pos = list;   // 头结点
    // 先遍历元素,再打印其值
    printf("listhead=%p: ",list);

    if (list->next == list)  {  // 只有头结点,没有有效数据
        printf("list is null\n");
        return;
    }
    pos = pos->next;    // 第一个节点开始
    while(pos != list){
        printf("%d, ",pos->data);
        pos = pos->next;
    }
    printf("\n");
}

// 在第i个节点前面插入新元素(有头结点)
int CircularListInsert(CircularList list, int i, ElemType e)
{
    CircularList pos = list;
    // head ==> head new
    // head 1 3 ==> head 1 new 3 , i =2
    // head 1 2 ==> head 1 2 new , i =3
    /*  1.找到插入位置的前一个节点
     *  2.分配新节点,将新节点插入到链表中
     */
    for(int k=1; k <= i-1; k++) {
        pos = pos->next;
        if (pos == list)  {  // 插入位置超出链表长度
            printf("insert location error\n");
            return -1;
        }
    }
    CircularList new = NewCircularListNode();
    // pos为新插入位置的前一项
    new->data = e;
    new->next = pos->next; //新节点的next指向(插入位置前一项的后一项)
    pos->next = new;

    return 0;
}
// 删除第i个节点(有头结点)。
int CircularListDelete(CircularList list, int i)
{
    CircularList pos = list;
    /*  1.从链表中删除节点
     *  2.释放节点空间
     */
    if (list->next == list){    // 没有有效节点
        return -1;
    }
    for(int k=1; k <= i-1; k++) {
        pos = pos->next;
        if (pos == list)  {  // 插入位置超出链表长度
            printf("Delete location error\n");
            return -1;
        }
    }
    // pos是被删除节点的前一项
    CircularList delete = pos->next;    // 将被删除的节点
    pos->next = delete->next;
    free(delete);
    return 0;
}
// 链表拼接 = list1 list2, 只保留list1的头结点。拼接完成后表2的结构已经被破坏。
/*			p3
    head1 		p2
            p1

            p6
    head2 		p5
            p4
    步骤:
        1.找到表1的尾结点
        2.找到表2的尾结点
        3.将表2中的所有非头结点组成的单链表插入到表1中
                    p6	p5	p4
            head1
                    p1	p2	p3
        4.释放表2的头结点
    */
int SpliceList(CircularList list1, CircularList list2)
{
    CircularList listTail1 = list1->next; // 表1的尾结点
    CircularList listTail2 = list2->next; // 表1的尾结点

    //printf("list1=%p, list2=%p\n", list1, list2);
    if (!list1 || !list2)
        return -1;
    // list2只有头结点,不用拼接.
    if (listTail2 == list2)
        return 0;

    /* 1.找到表1的尾结点 */
    while(1) {
        if (listTail1->next == list1)
            break;
        listTail1 = listTail1->next;
        //printf("listTail1=%p\n", listTail1);
    }
    /* 2.找到表2的尾结点 */
    while(1) {
        if (listTail2->next == list2)
            break;
        listTail2 = listTail2->next;
       // printf("listTail2=%p\n", listTail2);
    }
    //printf("listTail1->next=%p, listTail2->next=%p\n", listTail1->next, listTail2->next);
    /* 3.将表2中的所有非头结点组成的单链表插入到表1中 */
    listTail1->next = list2->next;
    listTail2->next = list1;

    /* 4.释放表2的头结点 */
    free(list2);
    return 0;
}

#endif // CIRCULARLIST_H

 

你可能感兴趣的:(算法与数据结构)