C语言数据结构:单向链表

线性表是最常用且最简单的一种数据结构。一个线性表是多个数据元素的序列,数据元素的具体含义可以根据自己的情况实现,而一个数据元素又可以由若干个数据项组成。下面用单向链表的方式实现线性表,数据元素仅有一个int型变量和指向下一节点的数据指针。程序的功能有插入,删除,修改,判断相等的数据是否存在,计算链表长度,根据位置返回节点值,排序和就地逆置。

#include <stdio.h>
#include <stdlib.h>

typedef struct _listNode{
    int value;
    struct _listNode * next;
}listNode, *pListNode;

pListNode List_create(int);

void List_destroy(pListNode head);

int List_getListLength(pListNode head);

int List_getNode(pListNode head, int pos, pListNode myNode);
// 0 presents no node at pos

int List_isExisting(pListNode head, pListNode myNode);
// 0 presents not exist, positive number is the position of the same-value node

pListNode List_insert(pListNode head, int pos, pListNode myNode);
// insert node at pos

pListNode List_delete(pListNode head, int pos, pListNode myNode);

void List_union(pListNode head1, pListNode head2);
// head1 is the new list

void List_modify(pListNode head, int pos, pListNode myNode);
// replace node contents at pos with myNode

pListNode List_ascendingSort(pListNode head);

pListNode List_localReverse(pListNode head);

void List_displayAll(pListNode head);

int main()
{
    // these are test nodes
    pListNode insert0 = List_create(0);
    pListNode insert_1 = List_create(-1);
    pListNode insert2 = List_create(2);
    pListNode insert9 = List_create(9);

    // head node
    pListNode head = List_create(5);
    List_displayAll(head);

    // test insert operation
    // insert before head
    head = List_insert(head, 1, insert0);
    printf("insert 0 before head.\n");
    List_displayAll(head);
    // insert between
    head = List_insert(head, 2, insert_1);
    printf("insert -1 at pos 2.\n");
    List_displayAll(head);
    // insert at tail
    head = List_insert(head, 4, insert2);
    printf("insert 2 at tail.\n");
    List_displayAll(head);
    head = List_insert(head, 4, insert9);
    printf("insert 9 at pos 4.\n");
    List_displayAll(head);
    printf("\n");

    // test get length operation
    int len = List_getListLength(head);
    printf("list length is: %d\n\n", len);

    // test get node operation
    pListNode temp = List_create(0);
    printf("temp node value is: %d\n", temp->value);
    List_getNode(head, 2, temp);
    printf("after get node operation with pos 2, temp value is: %d\n", temp->value);
    printf("before modify:\n");
    List_displayAll(head);
    printf("after modify with value %d at pos 1:\n", temp->value);
    List_modify(head, 1, temp);
    List_displayAll(head);
    printf("\n");

    // test is existing operation
    int pos = List_isExisting(head, temp);
    printf("is existing operation with value -1, result is: %d\n\n", pos);

    // test delete operation
    // delete head
    head = List_delete(head, 1, temp);
    printf("delete head.\n");
    List_displayAll(head);
    head = List_delete(head, 2, temp);
    printf("delete node with pos 2.\n");
    List_displayAll(head);
    head = List_delete(head, List_getListLength(head), temp);
    printf("delete tail.\n");
    List_displayAll(head);
    printf("\n");

    // test union operation
    pListNode head1 = List_create(10);
    pListNode node = List_create(21);
    head1 = List_insert(head1, 1, node);
    printf("list 2 is: \n");
    List_displayAll(head1);
    printf("after union operation:\n");
    List_union(head, head1);
    List_displayAll(head);
    printf("\n");

    // test ascending operation
    printf("after ascending operation:\n");
    head = List_ascendingSort(head);
    List_displayAll(head);
    printf("\n");

    // test local reverse operation
    printf("after local reverse operation:\n");
    head = List_localReverse(head);
    List_displayAll(head);
    printf("\n");

    // test destroy operation
    printf("after destroy operation:\n");
    List_destroy(head);
    printf("head value is invalid: %d\n\n", head->value);

    system("pause");

    return 0;
}

pListNode List_create(int value){
    pListNode head = (pListNode)malloc(sizeof(listNode));
    if(head == NULL){
        printf("Have no space for head node.\n");
    }
    head->value = value;
    head->next = NULL;
    return head;
}

void List_destroy(pListNode head){
    pListNode previous = NULL, current = head;
    while(current != NULL){
        previous = current;
        current = current->next;
        free(previous);
    }

}

int List_getListLength(pListNode head){
    int count = 0;
    pListNode current = head;
    while(current != NULL){
        current = current->next;
        count++;
    }
    return count;
}

// 0 presents no node at pos
int List_getNode(pListNode head, int pos, pListNode myNode){
    if(pos < 1 || pos >= List_getListLength(head)){
        printf("wrong position when get node.\n");
        return 0;
    }
    int i = 1;
    pListNode current = head;
    while(i != pos){
        current = current->next;
        i++;
    }
    myNode->value = current->value;
    myNode->next = NULL;
    return 1;
}

// 0 presents not exist, positive number is the position of the same-value node
int List_isExisting(pListNode head, pListNode myNode){
    int pos = 0, tag = 0;
    pListNode current = head;
    while(current != NULL){
        pos++;
        if(current->value == myNode->value){
            tag = 1;
            break;
        }
        current = current->next;
    }
    if(tag == 0){
        pos = 0;
    }
    return pos;
}

// insert myNode at pos
pListNode List_insert(pListNode head, int pos, pListNode myNode){
    if(pos < 1 || pos > List_getListLength(head)+1){
        printf("wrong position when insert node.\n");
        return head;
    }
    // insert before head
    if(pos == 1){
        myNode->next = head;
        head = myNode;
        return head;
    }
    // insert into the list
    int i = 1;
    pListNode previous = NULL, current = head;
    while(current != NULL){
        previous = current;
        current = current->next;
        i++;
        if(i == pos){
            break;
        }
    }
    previous->next = myNode;
    myNode->next = current;
    return head;
}

pListNode List_delete(pListNode head, int pos, pListNode myNode){
    if(pos < 1 || pos > List_getListLength(head)){
        printf("wrong position when delete node.\n");
        return head;
    }
    // judge if list is empty
    if(head == NULL){
        printf("list is empty, can't be delete.\n");
        return head;
    }
    // delete head
    pListNode current = head;
    if(pos == 1){
        head = head->next;
        free(current);
        return head;
    }
    // other situation
    int i = 1;
    for(i = 1; i < pos - 1; i++){
        current = current->next;
    }
    pListNode deleteNode = current->next;
    current->next = deleteNode->next;
    myNode->value = deleteNode->value;
    free(deleteNode);
    return head;
}

// head1 is the new list
void List_union(pListNode head1, pListNode head2){
    if(head1 == NULL){
        printf("parameter is type of NULL, exit.\n");
        return;
    }
    pListNode current = head1;
    for(; current->next != NULL; current = current->next);
    current->next = head2;
}

// replace node contents at pos with myNode
void List_modify(pListNode head, int pos, pListNode myNode){
    if(head == NULL || myNode == NULL){
        printf("head or node is type of NULL, exit.\n");
        return;
    }
    if(pos < 1 || pos > List_getListLength(head)){
        printf("wrong position when modify node.\n");
        return;
    }
    int i = 1;
    pListNode current = head;
    for(; i < pos; i++, current = current->next);
    current->value = myNode->value;
}

pListNode List_ascendingSort(pListNode head){
    if(head == NULL){
        printf("head is NULL.\n");
        return head;
    }
    // bubble sort
    pListNode current = head;
    int temp = 0;
    int i = 0, j = 0, k = List_getListLength(head);
    for(i = 0; i < k; i++){
        current = head;
        for(j = 0; j < i; j++){
            current = current->next;
        }
        for(j = i; j < k-1; j++){
            if(current->value > current->next->value){
                temp = current->value;
                current->value = current->next->value;
                current->next->value = temp;
            }
            current = current->next;
        }
    }
    return head;
}

pListNode List_localReverse(pListNode head){
    pListNode p = head, q = NULL;
    head = NULL;
    while(p){
        q = p->next;
        p->next = head;
        head = p;
        p = q;
    }
    return head;
}

void List_displayAll(pListNode head){
    if(head == NULL){
        printf("head is NULL, exit\n");
        return;
    }
    pListNode current = head;
    printf("list is: ");
    for(; current != NULL; current = current->next){
        printf("\t%d", current->value);
    }
    printf("\n");
}

下面是测试结果

list is:        5
insert 0 before head.
list is:        0       5
insert -1 at pos 2.
list is:        0       -1      5
insert 2 at tail.
list is:        0       -1      5       2
insert 9 at pos 4.
list is:        0       -1      5       9       2

list length is: 5

temp node value is: 0
after get node operation with pos 2, temp value is: -1
before modify:
list is:        0       -1      5       9       2
after modify with value -1 at pos 1:
list is:        -1      -1      5       9       2

is existing operation with value -1, result is: 1

delete head.
list is:        -1      5       9       2
delete node with pos 2.
list is:        -1      9       2
delete tail.
list is:        -1      9

list 2 is:
list is:        21      10
after union operation:
list is:        -1      9       21      10

after ascending operation:
list is:        -1      9       10      21

after local reverse operation:
list is:        21      10      9       -1

after destroy operation:
head value is invalid: 7025048
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值