在計算機科學中,數據結構是組織和存儲數據的方式,以便能夠高效地訪問和修改數據。單鏈表是一種常見的數據結構,廣泛應用于各種算法和程序中。本文將詳細介紹單鏈表的基本概念、存儲結構、基本操作以及應用實例,并通過C語言代碼進行實例分析。
單鏈表(Singly Linked List)是一種線性數據結構,由一系列節點組成,每個節點包含兩個部分:數據域和指針域。數據域用于存儲數據,指針域用于指向下一個節點。單鏈表的特點是每個節點只有一個指向下一個節點的指針,因此只能單向遍歷。
單鏈表的存儲結構可以用C語言中的結構體來表示:
struct Node {
int data; // 數據域
struct Node* next; // 指針域,指向下一個節點
};
在這個結構體中,data表示節點存儲的數據,next是指向下一個節點的指針。
創建單鏈表的過程包括初始化頭節點和添加新節點。頭節點是單鏈表的起點,通常不存儲實際數據。
struct Node* createLinkedList(int data) {
struct Node* head = (struct Node*)malloc(sizeof(struct Node));
head->data = data;
head->next = NULL;
return head;
}
在單鏈表中插入節點有多種方式,包括在鏈表頭部插入、在鏈表尾部插入以及在指定位置插入。
void insertAtHead(struct Node** head, int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = *head;
*head = newNode;
}
void insertAtTail(struct Node** head, int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
if (*head == NULL) {
*head = newNode;
return;
}
struct Node* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
void insertAtPosition(struct Node** head, int data, int position) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
if (position == 1) {
newNode->next = *head;
*head = newNode;
return;
}
struct Node* temp = *head;
for (int i = 1; i < position - 1 && temp != NULL; i++) {
temp = temp->next;
}
if (temp == NULL) {
printf("Position out of range\n");
return;
}
newNode->next = temp->next;
temp->next = newNode;
}
刪除節點的操作包括刪除頭節點、刪除尾節點以及刪除指定位置的節點。
void deleteAtHead(struct Node** head) {
if (*head == NULL) {
printf("List is empty\n");
return;
}
struct Node* temp = *head;
*head = (*head)->next;
free(temp);
}
void deleteAtTail(struct Node** head) {
if (*head == NULL) {
printf("List is empty\n");
return;
}
if ((*head)->next == NULL) {
free(*head);
*head = NULL;
return;
}
struct Node* temp = *head;
while (temp->next->next != NULL) {
temp = temp->next;
}
free(temp->next);
temp->next = NULL;
}
void deleteAtPosition(struct Node** head, int position) {
if (*head == NULL) {
printf("List is empty\n");
return;
}
struct Node* temp = *head;
if (position == 1) {
*head = temp->next;
free(temp);
return;
}
for (int i = 1; i < position - 1 && temp != NULL; i++) {
temp = temp->next;
}
if (temp == NULL || temp->next == NULL) {
printf("Position out of range\n");
return;
}
struct Node* nodeToDelete = temp->next;
temp->next = nodeToDelete->next;
free(nodeToDelete);
}
查找節點可以通過遍歷鏈表來實現,找到指定數據的節點并返回其位置。
int searchNode(struct Node* head, int data) {
struct Node* temp = head;
int position = 1;
while (temp != NULL) {
if (temp->data == data) {
return position;
}
temp = temp->next;
position++;
}
return -1; // 未找到
}
遍歷單鏈表是指依次訪問鏈表中的每個節點,并輸出其數據。
void printLinkedList(struct Node* head) {
struct Node* temp = head;
while (temp != NULL) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
假設我們需要實現一個簡單的學生信息管理系統,使用單鏈表來存儲學生的信息。每個學生的信息包括學號、姓名和成績。
struct Student {
int id;
char name[50];
float grade;
struct Student* next;
};
void insertStudent(struct Student** head, int id, char name[], float grade) {
struct Student* newStudent = (struct Student*)malloc(sizeof(struct Student));
newStudent->id = id;
strcpy(newStudent->name, name);
newStudent->grade = grade;
newStudent->next = *head;
*head = newStudent;
}
void printStudents(struct Student* head) {
struct Student* temp = head;
while (temp != NULL) {
printf("ID: %d, Name: %s, Grade: %.2f\n", temp->id, temp->name, temp->grade);
temp = temp->next;
}
}
int main() {
struct Student* head = NULL;
insertStudent(&head, 1, "Alice", 95.5);
insertStudent(&head, 2, "Bob", 88.0);
insertStudent(&head, 3, "Charlie", 92.3);
printStudents(head);
return 0;
}
單鏈表可以用于表示多項式,每個節點存儲多項式的一項(系數和指數)。我們可以通過遍歷兩個多項式鏈表來實現多項式相加。
struct Term {
int coefficient;
int exponent;
struct Term* next;
};
void insertTerm(struct Term** head, int coefficient, int exponent) {
struct Term* newTerm = (struct Term*)malloc(sizeof(struct Term));
newTerm->coefficient = coefficient;
newTerm->exponent = exponent;
newTerm->next = *head;
*head = newTerm;
}
struct Term* addPolynomials(struct Term* poly1, struct Term* poly2) {
struct Term* result = NULL;
while (poly1 != NULL && poly2 != NULL) {
if (poly1->exponent > poly2->exponent) {
insertTerm(&result, poly1->coefficient, poly1->exponent);
poly1 = poly1->next;
} else if (poly1->exponent < poly2->exponent) {
insertTerm(&result, poly2->coefficient, poly2->exponent);
poly2 = poly2->next;
} else {
int sum = poly1->coefficient + poly2->coefficient;
if (sum != 0) {
insertTerm(&result, sum, poly1->exponent);
}
poly1 = poly1->next;
poly2 = poly2->next;
}
}
while (poly1 != NULL) {
insertTerm(&result, poly1->coefficient, poly1->exponent);
poly1 = poly1->next;
}
while (poly2 != NULL) {
insertTerm(&result, poly2->coefficient, poly2->exponent);
poly2 = poly2->next;
}
return result;
}
void printPolynomial(struct Term* head) {
struct Term* temp = head;
while (temp != NULL) {
printf("%dx^%d", temp->coefficient, temp->exponent);
if (temp->next != NULL) {
printf(" + ");
}
temp = temp->next;
}
printf("\n");
}
int main() {
struct Term* poly1 = NULL;
insertTerm(&poly1, 5, 2);
insertTerm(&poly1, 4, 1);
insertTerm(&poly1, 2, 0);
struct Term* poly2 = NULL;
insertTerm(&poly2, 3, 1);
insertTerm(&poly2, 1, 0);
struct Term* result = addPolynomials(poly1, poly2);
printPolynomial(result);
return 0;
}
單鏈表是一種簡單而強大的數據結構,適用于需要頻繁插入和刪除操作的場景。通過本文的介紹,我們了解了單鏈表的基本概念、存儲結構、基本操作以及應用實例。雖然單鏈表在某些方面存在不足,但其靈活性和動態內存分配的特點使其在許多應用中仍然具有重要價值。掌握單鏈表的操作和應用,對于理解和實現更復雜的數據結構和算法具有重要意義。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。