C语言数据结构_单链表

本文介绍了链表的基本操作,包括创建头结点、创建节点、打印链表、插入元素(头插、尾插、中间插入、按值插入)、删除元素(按值删除、按位置删除)。此外,还展示了两种不同的实现方式,通过比较不同实现的代码来理解链表操作的原理。
摘要由CSDN通过智能技术生成

单链表

1.创建一个头结点并初始化
自写的


struct Node
{
    int data;          //数据域
    struct Node *next; //指针域
};
//创建一个头节点注意初始化
struct Node *createList()
{
    struct Node *headNode = (struct Node *)malloc(sizeof(struct Node));
    headNode->data = '\0';
    headNode->next = NULL;
    return headNode;
}

在这里插入图片描述

老师的

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;

2.创建结点
自写的

//创建节点
struct Node *creatNode(int data)
{
    struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

3.打印链表
自写的

//打印链表
void printList(struct Node *headNode)
{
    struct Node *pMove = headNode->next;
    while (pMove != NULL)
    {
        printf("%d ", pMove->data);
        pMove = pMove->next;
    }
    printf("\n");
}

老师的

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 insertNodeByHead(struct Node *headNode, int data)
{
    struct Node *newNode = creatNode(data);
    printf("开始从头部连接%d\n", data);
    newNode->next = headNode->next;
    headNode->next = newNode;
}
//尾插法连接各个节点
void insertNodeByTail(struct Node *headNode, int data)
{
    struct Node *newNode = creatNode(data);
    struct Node *pMove = headNode;
    while (pMove->next != NULL)
    {
        pMove = pMove->next;
    }
    printf("开始从尾部连接%d\n", data);
    pMove->next = newNode;
}
//在中间连接一个节点
void insertNodeBymiddle(struct Node *headNode, int data, int position)
{
    struct Node *newNode = creatNode(data);
    struct Node *pMove = headNode;
    for (int i = 0; i < position; i++)
    {
        pMove = pMove->next;
        if (pMove == NULL)
        {
            printf("输入的位置%d超出了链表的最大长不能插入元素。\n", position);
            return;
        }
    }
    //实际上是在该位置的后面插入一个节点
    printf("开始从中间连接%d\n", data);
    newNode->next = pMove->next;
    pMove->next = newNode;
}
//在指定值后面插入一个节点
void insertNodeByData(struct Node *headNode, int paraData, int Data)
{
    struct Node *newNode = creatNode(Data);
    struct Node *pMove = headNode->next;
    while (pMove->data != paraData)
    {
        if (pMove == NULL)
        {
            printf("未能找到该元素,无法添加。\n");
            return;
        }
         pMove = pMove->next;//特别注意这里尤其考虑该值在最后的时候
         //pMove和pMove->next不一样
    }
    printf("在%d后面添加元素%d\n", paraData, Data);
    newNode->next = pMove->next;
    pMove->next = newNode;
}

在这里插入图片描述

老师的

//w尾插法
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.
	//找到1尾部
	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 paraPosition){
	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

5.删除元素
自写的

//链表的指定值的删除方法一
void deleteNodeByAppionWayOne(struct Node *headNode, int posData)
{
    struct Node *posNode = headNode->next;
    struct Node *posNodeFront = headNode;
    if (posNode == NULL)
    {
        printf("链表为空无法删除。\n");
    }
    else
    {
        while (posNode->data != posData)
        {
            posNodeFront = posNode;
            posNode = posNodeFront->next;
            if (posNode == NULL)
            {
                printf("没有找到%d的信息,无法删除。\n", posData);
                return;
            }
        }
        printf("删除%d\n", posData);
        posNodeFront->next = posNode->next;
        free(posNode);
    }
}
//链表的指定值删除方法二
void deleteNodeByAppionWayTwo(struct Node *headNode, int posData)
{
    struct Node *p;
    struct Node *q;
    p = headNode;
    while (p->next != NULL && p->next->data != posData)
    {
        p = p->next;
    }
    if (p->next == NULL)
    {
        printf("没有找到%d的信息,无法删除。\n", posData);
        return;
    }
    printf("删除 %d\n", posData);
    q = p->next;
    p->next = p->next->next;
    free(q);
}
//链表的指定位置删除
void deleteNodeByposition(struct Node *headNode, int position)
{
    struct Node *pMove = headNode;
    struct Node *q;
    if (position <= 0)
    {
        printf("无效位置 %d。\n", position);
        return;
    }
    for (int i = 1; i < position; i++)
    {
        pMove = pMove->next;
    }
    if (pMove->next == NULL)
    {
        printf("要删除的位置 %d 已经超出链表的最大长度不能删除该位置。\n", position);
        return;
    }
    printf("删除位置 %d 的元素\n", position);
    q = pMove->next;
    pMove->next = pMove->next->next;
    free(q);
}

在这里插入图片描述

老师的

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 deleteElement

6.所有代码
自写的

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

struct Node
{
    int data;          //数据域
    struct Node *next; //指针域
};
//创建一个头节点注意初始化
struct Node *createList()
{
    struct Node *headNode = (struct Node *)malloc(sizeof(struct Node));
    headNode->data = '\0';
    headNode->next = NULL;
    return headNode;
}
//创建节点
struct Node *creatNode(int data)
{
    struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}
//打印链表
void printList(struct Node *headNode)
{
    struct Node *pMove = headNode->next;
    while (pMove != NULL)
    {
        printf("%d ", pMove->data);
        pMove = pMove->next;
    }
    printf("\n");
}
//头插法连接各个节点
void insertNodeByHead(struct Node *headNode, int data)
{
    struct Node *newNode = creatNode(data);
    printf("开始从头部连接%d\n", data);
    newNode->next = headNode->next;
    headNode->next = newNode;
}
//尾插法连接各个节点
void insertNodeByTail(struct Node *headNode, int data)
{
    struct Node *newNode = creatNode(data);
    struct Node *pMove = headNode;
    while (pMove->next != NULL)
    {
        pMove = pMove->next;
    }
    printf("开始从尾部连接%d\n", data);
    pMove->next = newNode;
}
//在中间连接一个节点
void insertNodeBymiddle(struct Node *headNode, int data, int position)
{
    struct Node *newNode = creatNode(data);
    struct Node *pMove = headNode;
    for (int i = 0; i < position; i++)
    {
        pMove = pMove->next;
        if (pMove == NULL)
        {
            printf("输入的位置%d超出了链表的最大长不能插入元素。\n", position);
            return;
        }
    }
    //实际上是在该位置的后面插入一个节点
    printf("开始从中间连接%d\n", data);
    newNode->next = pMove->next;
    pMove->next = newNode;
}
//在指定值后面插入一个节点
void insertNodeByData(struct Node *headNode, int paraData, int Data)
{
    struct Node *newNode = creatNode(Data);
    struct Node *pMove = headNode->next;
    while (pMove->data != paraData)
    {
        pMove = pMove->next;
        if (pMove == NULL)
        {
            printf("未能找到该元素,无法添加。\n");
            return;
        }
    }
    printf("在%d后面添加元素%d\n", paraData, Data);
    newNode->next = pMove->next;
    pMove->next = newNode;
}
//链表的指定值的删除方法一
void deleteNodeByAppionWayOne(struct Node *headNode, int posData)
{
    struct Node *posNode = headNode->next;
    struct Node *posNodeFront = headNode;
    if (posNode == NULL)
    {
        printf("链表为空无法删除。\n");
    }
    else
    {
        while (posNode->data != posData)
        {
            posNodeFront = posNode;
            posNode = posNodeFront->next;
            if (posNode == NULL)
            {
                printf("没有找到%d的信息,无法删除。\n", posData);
                return;
            }
        }
        printf("删除%d\n", posData);
        posNodeFront->next = posNode->next;
        free(posNode);
    }
}
//链表的指定值删除方法二
void deleteNodeByAppionWayTwo(struct Node *headNode, int posData)
{
    struct Node *p;
    struct Node *q;
    p = headNode;
    while (p->next != NULL && p->next->data != posData)
    {
        p = p->next;
    }
    if (p->next == NULL)
    {
        printf("没有找到%d的信息,无法删除。\n", posData);
        return;
    }
    printf("删除 %d\n", posData);
    q = p->next;
    p->next = p->next->next;
    free(q);
}
//链表的指定位置删除
void deleteNodeByposition(struct Node *headNode, int position)
{
    struct Node *pMove = headNode;
    struct Node *q;
    if (position <= 0)
    {
        printf("无效位置 %d。\n", position);
        return;
    }
    for (int i = 1; i < position; i++)
    {
        pMove = pMove->next;
    }
    if (pMove->next == NULL)
    {
        printf("要删除的位置 %d 已经超出链表的最大长度不能删除该位置。\n", position);
        return;
    }
    printf("删除位置 %d 的元素\n", position);
    q = pMove->next;
    pMove->next = pMove->next->next;
    free(q);
}
void allTest()
{
    //创建一个链表
    struct Node *List = createList();
    insertNodeByHead(List, 1);
    insertNodeByHead(List, 2);
    insertNodeByHead(List, 3);
    insertNodeByHead(List, 4);
    printList(List);
    //测试根据元素值删除方法一
    deleteNodeByAppionWayOne(List, 2);
    printList(List);
    deleteNodeByAppionWayOne(List, 7);
    printList(List);
    //测试尾插法
    insertNodeByTail(List, 10);
    printList(List);
    //测试中间插入元素
    insertNodeBymiddle(List, 20, 2);
    printList(List);
    insertNodeBymiddle(List, 11, 10);
    printList(List);
    //测试根据元素值删除方式二
    deleteNodeByAppionWayTwo(List, 10);
    printList(List);
    deleteNodeByAppionWayTwo(List, 2);
    printList(List);
    // 测试根据位置删除
    deleteNodeByposition(List, 0);
    printList(List);
    deleteNodeByposition(List, 1);
    printList(List);
    //测试指定值后面插入元素
    insertNodeByData(List, 20, 23);
    printList(List);
}
int main()
{
    allTest();
}

老师的`

#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 paraChar 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 paraPosition){
	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 deleteElement

/**
 * Unit test.
 */
//测试插入删除
void appendInsertDeleteTest(){
	// 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(){
	appendInsertDeleteTest();
    basicAddressTest();
}// Of main

7.测试结果
自写的

开始从头部连接1
开始从头部连接2
开始从头部连接3
开始从头部连接4
4 3 2 1
删除2
4 3 1
没有找到7的信息,无法删除。
4 3 1
开始从尾部连接10
4 3 1 10
开始从中间连接20
4 3 20 1 10
输入的位置10超出了链表的最大长不能插入元素。
4 3 20 1 10
删除 10
4 3 20 1
没有找到2的信息,无法删除。
4 3 20 1
无效位置 04 3 20 1
删除位置 1 的元素
3 20 120后面添加元素23
3 20 23 1

老师的

Hello!
Cannot delete a
Hll!
linking
Holl!
The first node: 6421984, 6421984, 6421992
The second node: 6421968, 6421968, 6421976
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个使用C语言实现单链表的例子: ```c #include <stdio.h> #include <stdlib.h> typedef struct node { int value; struct node *next; } Node; typedef struct linked_list { Node *head; } LinkedList; void add(LinkedList *list, int value) { Node *newNode = (Node*)malloc(sizeof(Node)); newNode->value = value; newNode->next = NULL; if (list->head == NULL) { list->head = newNode; } else { Node *current = list->head; while (current->next != NULL) { current = current->next; } current->next = newNode; } } void removeNode(LinkedList *list, int value) { if (list->head == NULL) { return; } if (list->head->value == value) { Node *temp = list->head; list->head = list->head->next; free(temp); return; } Node *current = list->head; while (current->next != NULL && current->next->value != value) { current = current->next; } if (current->next != NULL) { Node *temp = current->next; current->next = current->next->next; free(temp); } } void print(LinkedList *list) { Node *current = list->head; while (current != NULL) { printf("%d ", current->value); current = current->next; } printf("\n"); } int main() { LinkedList *list = (LinkedList*)malloc(sizeof(LinkedList)); list->head = NULL; add(list, 1); add(list, 2); add(list, 3); print(list); removeNode(list, 2); print(list); return 0; } ``` 这个单链表包含了三个函数:add、removeNode和print。add函数用于向单链表中添加一个元素,removeNode函数用于从单链表中删除一个元素,print函数用于打印单链表中所有元素的值。使用这个单链表,我们可以方便地对一系列元素进行管理和操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值