C语言数据结构学习(2):单链表

183 阅读4分钟

一、单链表的定义

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

二、单链表的组成结构

单链表由若干个结点连接而成,而每个节点又包括数据域与指针域。前一个结点的指针域与后一个结点的数据域相连,以此构成链表。

三、链表的具体构建

1.构建用于储存数据的结构体

typedef struct LinkNode{
    char data;
    struct LinkNode *next;
} LNode, *LinkList, *NodePtr;

2.构建结点初始化函数

LinkList initLinkList(){
    NodePtr tempHeader = (NodePtr)malloc(sizeof(LNode));
    tempHeader->data = '\0';
    tempHeader->next = NULL;
    return tempHeader;
}

3.构建打印全链表函数

void printList(NodePtr paraHeader){
    NodePtr p = paraHeader->next;
    while (p != NULL) {
        printf("%c", p->data);
        p = p->next;
    }// Of while
    printf("\r\n");
}

4.构建在链表末尾增加结点函数

void appendElement(NodePtr paraHeader, char paraChar){
    NodePtr p, q;

    //step 1. Construct a new node.
    q = (NodePtr)malloc(sizeof(LNode));
    q->data = paraChar;
    q->next = NULL;

    //step 2. Search to the tail.
    p = paraHeader;
    while (p->next != NULL) {
        p = p->next;
    }// Of while 

    //step 3. Now add/link.
    p->next = q;
}

5.构建插入结点函数

void insertElement(NodePtr paraHeader, char paraChar, int paraPositon){
    NodePtr p, q;

    // Step 1. Search to the position.
    p = paraHeader;
    for (int i = 0; i < paraPosition; i ++) {
        p = p->next;
        if (p == NULL) {
            printf("The position %d is beyond the scope of the list.",paraPosition);
            return;
        }// Of if
    } // Of for i

    //step 2. Construct a new node.
    q = (NodePtr)malloc(sizeof(LNode));
    q->data = paraChar;

    // Step 3. Now link.
    printf("linking\r\n");
    q->next = p->next;
    p->next = q;
}

6.构建删除结点函数

void deleteElement(NodePtr paraHeader, char paraChar) {
    NodePtr p, q;
    p = paraHeader;
    while ((p->next != NULL) && (p->next->data != paraChar)){
        p = p->next;
    }// Of while

    if (p->next == NULL) {
        printf("Cannot delete %c\r\n", paraChar);
        return;
    }// Of if

    q = p->next;
    p->next = p->next->next;
    free(q);
}

7.指定位置进行插入

void appendInsertDeleTest(){
    // Step 1. Initialize an empty list.
    LinkList tempList = initLinkList();
    printList(tempList);

    // Step 2. Add some characters.
    appendElement(tempList, 'H');
    appendElement(tempList, 'e');
    appendElement(tempList, 'l');
    appendElement(tempList, 'l');
    appendElement(tempList, 'o');
    appendElement(tempList, '!');
    printList(tempList);

    // Step 3. Delete some characters (the first occurrence).
    deleteElement(tempList, 'e');
    deleteElement(tempList, 'a');
    deleteElement(tempList, 'o');
    printList(tempList);

    // Step 4. Insert to a given position.
    insertElement(tempList, 'o', 1);
    printList(tempList);
}

8.打印结点

oid basicAddressTest(){
    LNode tempNode1, tempNode2;

    tempNode1.data = 4;
    tempNode1.next = NULL;

    tempNode2.data = 6;
    tempNode2.next = NULL;

    printf("The first node: %d, %d, %d\r\n", &tempNode1, &tempNode1.data, &tempNode1.next);
    printf("The second node: %d, %d, %d\r\n", &tempNode2, &tempNode2.data, &tempNode2.next);

    tempNode1.next = &tempNode2;
}

9.主函数

int main(){
    appendInsertDeleTest();
}

完整代码

#include<stdio.h>
#include<malloc.h>

/**
 * Linked list of characters. The key is data.
 */
typedef struct LinkNode{
    char data;
    struct LinkNode *next;
} LNode, *LinkList, *NodePtr;

/**
 * Initialize the list with a header.
 * @return The pointer to the header.
 */
LinkList initLinkList(){
    NodePtr tempHeader = (NodePtr)malloc(sizeof(LNode));
    tempHeader->data = '\0';
    tempHeader->next = NULL;
    return tempHeader;
}// Of initLinkList

/**
 * Print the list.
 * @param paraHeader The header of the list.
 */
void printList(NodePtr paraHeader){
    NodePtr p = paraHeader->next;
    while (p != NULL) {
        printf("%c", p->data);
        p = p->next;
    }// Of while
    printf("\r\n");
}// Of printList

/**
 * Add an element to the tail.
 * @param paraHeader The header of the list.
 * @param paraHeader The given char.
 */
void appendElement(NodePtr paraHeader, char paraChar){
    NodePtr p, q;

    //step 1. Construct a new node.
    q = (NodePtr)malloc(sizeof(LNode));
    q->data = paraChar;
    q->next = NULL;

    //step 2. Search to the tail.
    p = paraHeader;
    while (p->next != NULL) {
        p = p->next;
    }// Of while 

    //step 3. Now add/link.
    p->next = q;
}// Of appendElement

/**
 * Insert an element to the given position.
 * @param paraHeader The header of the list.
 * @param paraChar The given char.
 * @param paraPosition The given position.
 */
void insertElement(NodePtr paraHeader, char paraChar, int paraPositon){
    NodePtr p, q;

    // Step 1. Search to the position.
    p = paraHeader;
    for (int i = 0; i < paraPosition; i ++) {
        p = p->next;
        if (p == NULL) {
            printf("The position %d is beyond the scope of the list.",paraPosition);
            return;
        }// Of if
    } // Of for i

    //step 2. Construct a new node.
    q = (NodePtr)malloc(sizeof(LNode));
    q->data = paraChar;

    // Step 3. Now link.
    printf("linking\r\n");
    q->next = p->next;
    p->next = q;
}// Of insertElement

/**
 * Delete an element from the list.
 * @param paraHeader The header of the list.
 * @param paraChar The given char.
 */
void deleteElement(NodePtr paraHeader, char paraChar) {
    NodePtr p, q;
    p = paraHeader;
    while ((p->next != NULL) && (p->next->data != paraChar)){
        p = p->next;
    }// Of while

    if (p->next == NULL) {
        printf("Cannot delete %c\r\n", paraChar);
        return;
    }// Of if

    q = p->next;
    p->next = p->next->next;
    free(q);
}// Of deleElement

/**
 * Unit test
 */
void appendInsertDeleTest(){
    // Step 1. Initialize an empty list.
    LinkList tempList = initLinkList();
    printList(tempList);

    // Step 2. Add some characters.
    appendElement(tempList, 'H');
    appendElement(tempList, 'e');
    appendElement(tempList, 'l');
    appendElement(tempList, 'l');
    appendElement(tempList, 'o');
    appendElement(tempList, '!');
    printList(tempList);

    // Step 3. Delete some characters (the first occurrence).
    deleteElement(tempList, 'e');
    deleteElement(tempList, 'a');
    deleteElement(tempList, 'o');
    printList(tempList);

    // Step 4. Insert to a given position.
    insertElement(tempList, 'o', 1);
    printList(tempList);
}// Of appendInsertDeleteTest

/**
 * Address test: beyond the book.
 */
void basicAddressTest(){
    LNode tempNode1, tempNode2;

    tempNode1.data = 4;
    tempNode1.next = NULL;

    tempNode2.data = 6;
    tempNode2.next = NULL;

    printf("The first node: %d, %d, %d\r\n", &tempNode1, &tempNode1.data, &tempNode1.next);
    printf("The second node: %d, %d, %d\r\n", &tempNode2, &tempNode2.data, &tempNode2.next);

    tempNode1.next = &tempNode2;
}// Of basicAddressTest

/**
 * The entrance.
 */
int main(){
    appendInsertDeleTest();
}// Of main