单链表是计算机科学中数据结构的基础之一,它是由一系列节点构成的,每个节点包含一个数据元素和一个指向下一个节点的指针。在C语言中,我们通常通过定义结构体来实现链表的数据结构。本篇文章将深入探讨单链表的创建、排序、归并、插入、删除、定位、获取元素、计算元素个数以及打印链表等操作。 **1. 创建单链表** 创建单链表通常从创建头节点开始,头节点不存储任何数据,仅用于链接其他节点。之后,我们可以按需添加节点到链表的末尾或特定位置。例如,创建一个空链表可以这样实现: ```c typedef struct Node { int data; struct Node* next; } ListNode; ListNode* createNode(int data) { ListNode* newNode = (ListNode*)malloc(sizeof(ListNode)); newNode->data = data; newNode->next = NULL; return newNode; } ListNode* createLinkedList() { ListNode* head = createNode(0); // 头节点 return head; } ``` **2. 插入元素** 在链表中插入元素需要找到插入位置的前一个节点,然后将新节点插入。插入操作的时间复杂度为O(n),因为可能需要遍历整个链表。 ```c void insertNode(ListNode* head, int data, int index) { if (index < 0 || index > size(head)) return; // 检查索引的有效性 ListNode* newNode = createNode(data); ListNode* current = head; for (int i = 0; i < index - 1; i++) { current = current->next; } newNode->next = current->next; current->next = newNode; } ``` **3. 删除元素** 删除元素同样需要找到待删除节点的前一个节点,然后改变前一个节点的`next`指针。删除操作的时间复杂度也是O(n)。 ```c void deleteNode(ListNode* head, int key) { if (head == NULL) return; if (head->data == key) { ListNode* temp = head; head = head->next; free(temp); return; } ListNode* current = head; while (current->next != NULL && current->next->data != key) { current = current->next; } if (current->next != NULL) { ListNode* temp = current->next; current->next = current->next->next; free(temp); } } ``` **4. 定位和获取元素** 定位元素通常通过遍历链表来完成,而获取元素则需要提供索引来定位。 ```c ListNode* getNode(ListNode* head, int index) { ListNode* current = head; for (int i = 0; i < index; i++) { if (current != NULL) { current = current->next; } else { return NULL; } } return current; } int getElem(ListNode* head, int index) { ListNode* node = getNode(head, index); return node != NULL ? node->data : -1; } ``` **5. 计算元素个数** 计算链表的长度可以通过遍历链表计数来实现。 ```c int size(ListNode* head) { int count = 0; ListNode* current = head; while (current != NULL) { count++; current = current->next; } return count; } ``` **6. 排序链表** 链表的排序有多种方法,如冒泡排序、选择排序、插入排序等。这里以插入排序为例: ```c void sortLinkedList(ListNode* head) { if (head == NULL || head->next == NULL) return; ListNode* current = head; while (current->next != NULL) { ListNode* next = current->next; while (next != NULL) { if (current->data > next->data) { int temp = current->data; current->data = next->data; next->data = temp; } next = next->next; } current = current->next; } } ``` **7. 归并两个已排序的链表** 归并两个已排序的链表通常采用迭代或递归的方式。这里给出一个迭代的例子: ```c ListNode* mergeSortedLists(ListNode* l1, ListNode* l2) { ListNode dummy(-1), *tail = &dummy; while (l1 != NULL && l2 != NULL) { if (l1->data < l2->data) { tail->next = l1; l1 = l1->next; } else { tail->next = l2; l2 = l2->next; } tail = tail->next; } tail->next = l1 != NULL ? l1 : l2; return dummy.next; } ``` **8. 打印链表** 打印链表的所有元素通常从头节点开始,逐个输出每个节点的`data`值。 ```c void printList(ListNode* head) { ListNode* current = head; while (current != NULL) { printf("%d -> ", current->data); current = current->next; } printf("NULL\n"); } ``` 以上就是关于单链表的基本操作,这些操作是数据结构和算法学习中的基础,对于理解和实现更复杂的算法至关重要。掌握这些技能可以帮助你更好地处理实际编程问题,提高代码的效率和可读性。




































- 1


- 粉丝: 74
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源


