链表是一种常见的数据结构,用于存储一系列的元素,每个元素称为节点。在C语言中,链表通常通过结构体来实现。每个节点包含数据和一个指向下一个节点的指针。这里是一个简单的单链表的实现示例:
定义链表节点
首先,定义链表节点的结构体。这个结构体包含节点数据和一个指向下一个节点的指针。
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode {
int data;
struct ListNode *next;
} ListNode;
创建新节点
接下来,实现一个函数来创建新节点。
ListNode* createNode(int data) {
ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
if (newNode == NULL) {
printf("Memory allocation failed.\n");
return NULL;
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}
添加节点到链表
可以定义函数将新节点添加到链表的末尾。
void appendNode(ListNode **head, int data) {
ListNode *newNode = createNode(data);
if (*head == NULL) {
*head = newNode;
return;
}
ListNode *current = *head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
打印链表
定义一个函数来打印链表的所有元素。
void printList(ListNode *head) {
ListNode *current = head;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
计算链表长度
链表的长度是其包含的节点数量。可以通过遍历链表并计数来确定其长度。
int listLength(ListNode *head) {
int length = 0;
ListNode *current = head;
while (current != NULL) {
length++;
current = current->next;
}
return length;
}
索引访问
虽然链表不支持直接索引访问,但可以通过遍历链表来访问特定索引的节点。
ListNode* getNodeAtIndex(ListNode *head, int index) {
int count = 0;
ListNode *current = head;
while (current != NULL) {
if (count == index) {
return current;
}
count++;
current = current->next;
}
return NULL; // 如果索引超出链表长度
}
删除指定位置的元素
删除操作涉及找到指定位置的节点,并重新调整其前一个节点的 next
指针,使其指向要删除节点的下一个节点。
void deleteNodeAtIndex(ListNode **head, int index) {
// 空链表或负索引无效
if (*head == NULL || index < 0) return;
ListNode *current = *head;
if (index == 0) {
// 删除头节点
*head = current->next;
free(current);
return;
}
// 找到要删除节点的前一个节点
for (int i = 0; current != NULL && i < index - 1; i++) {
current = current->next;
}
// 如果index超出链表长度
if (current == NULL || current->next == NULL) return;
// 删除节点
ListNode *next = current->next->next;
free(current->next);
current->next = next;
}
在指定位置插入元素
插入操作涉及到创建一个新的节点,并将其插入到链表中指定的位置。
void insertNodeAtIndex(ListNode **head, int index, int data) {
if (index < 0) return; // 负索引无效
ListNode *newNode = createNode(data);
if (index == 0) {
// 在头部插入
newNode->next = *head;
*head = newNode;
return;
}
ListNode *current = *head;
for (int i = 0; current != NULL && i < index - 1; i++) {
current = current->next;
}
// 如果index超出链表长度
if (current == NULL) {
free(newNode);
return;
}
// 插入新节点
newNode->next = current->next;
current->next = newNode;
}
释放链表
最后,当链表不再需要时,应该释放其占用的内存。
void freeList(ListNode *head) {
ListNode *temp;
while (head != NULL) {
temp = head;
head = head->next;
free(temp);
}
}
使用链表
下面是如何在程序中创建和使用链表的示例:
int main(){
ListNode *head = NULL;
appendNode(&head, 1);
appendNode(&head, 2);
appendNode(&head, 4);
insertNodeAtIndex(&head, 2, 3);
deleteNodeAtIndex(&head, 1);
printlist(head);
freelist(head);
return 0;
}
在一个源项目里编写
#include<stdio.h>
#include<stdlib.h>
typedef struct ListNode{
int data;
struct ListNode *next;
} ListNode;
//Define the nodes of the linked list.
//You have to define "ListNode" twice.
ListNode *CreatNode(int data_new){
ListNode *ptr=(ListNode *)malloc(sizeof(ListNode));
//Utilize malloc to allocate memory.
if(ptr==NULL){
printf("Memory allocation failed.\n");
return 0;
}
ptr->data=data_new;
ptr->next=NULL;
return ptr;
}
void appendNode(ListNode **head,int data){
//Use the pointer to the pointer
ListNode *newNode=CreatNode(data);
if(*head==NULL){
*head=newNode;
return;
}//This happens when the list is empty.
ListNode *tmp_ptr=*head;
while(tmp_ptr->next!=NULL){
tmp_ptr=tmp_ptr->next;
}//Iterate until the last node, then add at the end.
tmp_ptr->next=newNode;
}
int listLength(ListNode *head){
int i=0;
if (head == NULL) {
return 0;
}
ListNode *ptr=head;
while(ptr->next!=NULL){
ptr=ptr->next;
i++;
}
return i+1;
//'i' is an array-like index.
}
ListNode* getNodeAtIndex(ListNode *head, int index) {
int count = 0;
ListNode *current = head;
while (current != NULL) {
if (count == index) {
return current;
}
count++;
current = current->next;
}
return NULL;
//If the index exceeds the length of the linked list.
}
void printlist(ListNode *head){
ListNode *ptr=head;
while(ptr!=NULL){
printf("%d",ptr->data);
//It has been dequoted.
ptr=ptr->next;
}
printf("\n");
}
void freelist(ListNode *head){
ListNode *ptr=head;
while(ptr!=NULL){
ListNode *next = ptr->next;
//Saves a pointer to the next node.
free(ptr);
//Release the current node.
ptr = next;
// Move to the next node,
}
}
void deleteNodeAtIndex(ListNode **head, int index){
if(*head==NULL||index<=0){
printf("error:List is empty or index inputted illegal.");
}
ListNode *ptr=*head;
if(index==0){
*head=ptr->next;
free(ptr);
return;
}
for(int i=0;i<index-1&&ptr!=NULL;i++){
ptr=ptr->next;
}
if(ptr==NULL||ptr->next==NULL)return;
ListNode *tmp=ptr->next->next;
free(ptr->next);
ptr->next=tmp;
}
void insertNodeAtIndex(ListNode **head, int index, int data){
if(index<=0){
printf("error:Index inputted illegal.");
return ;
}
ListNode *NewNode=CreatNode(data);
if(index==0||*head==NULL){
NewNode->next = *head;
*head = NewNode;
return;
}
ListNode *ptr=*head;
for(int i=0;i<index-1&&ptr!=NULL;i++){
ptr=ptr->next;
}
if(ptr==NULL||ptr->next==NULL){
free(NewNode);
return;
}
NewNode->next=ptr->next;
ptr->next=NewNode;
}
int main(){
ListNode *head = NULL;
appendNode(&head, 1);
appendNode(&head, 2);
appendNode(&head, 4);
insertNodeAtIndex(&head, 2, 3);
deleteNodeAtIndex(&head, 1);
printlist(head);
freelist(head);
return 0;
}