单链表 - 数据结构

 

 

线性表:n个数据元素的有限序列。一般指逻辑结构上的线性结构。当n=0时为空表。——栈、队列、串。

线性表的特点:

1)对于同一线性表的各数据元素必定具有相同的数据类型和长度;

2)数据元素之间的相对位置是线性的。

 

链表(Linked List):链接方式存储的线性表。

1)用一组任意的存储单元来存放线性表的结点;

2)在存储每个结点值的同时,必须存储指示其后继结点的地址。

链域(指针域):存放结点的直接后继的地址。

 

单链表(Single Linked List):每个结点只有一个链域的链表。

数据域:存储数据元素信息的域。

指针域:存储直接后继存储位置的域。

由于开始结点无前驱,故设头指针head指向开始结点。

终端结点无后继,故终端结点的指针域为空,即NULL。

在单链表中,取得第i个数据元素必须从头指针出发寻找,因此,单链表是非随机存取的存储结构。

  在单链表的第一个结点之前附设一个结点,称为头结点。头结点的指针域存储指向第一个结点的指针。 

/*
 *位置约定:第m个,以0开始计数。
 *位置为m,以1开始计数
 */

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

/* 链表节点 */
struct node
{
    int data;
    struct node *next;
};

/* 反转单链表,分别用3个指针,指向前一个,当前,下一个 
 * 修改链表头(指针),要用指针的指针
* 通过函数的方式修改指针,要用指针的指针
*/ static void reverse(struct node** head_ref) { struct node* prev = NULL; struct node* current = *head_ref; struct node* next; while(current != NULL) { next = current->next; current->next = prev; prev = current; current = next; } *head_ref = prev; } //使用递归的方法 static struct node* reverseRecall(struct node* head) { //最后一个节点会返回作为头部 if(head == NULL || head->next == NULL) return head; struct node* newHead = reverseRecall(head->next); //head->next表示剩下的部分 head->next->next = head; head->next = NULL; //原来的头节点next应该为NULL return newHead; } // 添加数据,头部插入 void push(struct node** head_ref, int new_data) { struct node* new_node = (struct node*) malloc(sizeof(struct node)); new_node->data = new_data; new_node->next = (*head_ref); (*head_ref) = new_node; } //打印链表 void printList(struct node* head) { struct node* temp = head; while(temp != NULL) { printf("%d ", temp->data); temp = temp->next; } } int length(struct node* head) { int n = 0; struct node* temp = head; while(temp != NULL) { n++; temp = temp->next; } return n; } void RemoveHead(struct node** head_ref) { if(*head_ref == NULL) { printf("there is no element in the list.\n"); return; } *head_ref = (*head_ref)->next; } /*不知道节点数N,只遍历一次就求出中间节点 *Q:当单链表长度为0时,报错 */ void SearchMid(struct node* head, struct node** mid) { struct node *p1, *p2; p1 = head; p2 = head; while((p2->next != NULL) && (p2->next->next != NULL)) { p2 = p2->next->next; p1 = p1->next; } *mid = p1; } /*Method1: 找出链表倒数第m个元素 *当m=0时,返回链表最后一个元素 *先求出链表的总长度len,然后顺序变量求出位置在len-m的元素 */ node* SearchLastMElement1(struct node* head, int m) { int len = length(head); if(m < 0 || m > len-1 || head == NULL) return NULL; struct node* temp = head; for(int i = 1; i < len-m; i++) temp = temp->next; return temp; } /*Method2: 找出链表倒数第m个元素 *当m=0时,返回链表最后一个元素 *当前位置指针p,指向第m个元素的指针pm, *确保两个指针之间相差m个元素,然后以同样的速度移动它们 *当pm到达链表末尾时,p指针就是指向倒数第m个元素了 */ node* SearchLastMElement2(struct node* head, int m) { struct node* p = head; struct node* pm = head; for(int i = 1; i <= m; i++) //使指针pm指向第m个元素 { if(pm->next != NULL) pm = pm->next; else return NULL; } while(pm->next != NULL) //同样的速度移动指针p和pm { p = p->next; pm = pm->next; } return p; } int main() { struct node* head = NULL; push(&head, 20); push(&head, 4); push(&head, 15); push(&head, 85); push(&head, 60); push(&head, 100); push(&head, 80); printList(head); reverse(&head); printf("\n==============================\nReversed Linked list \n"); printList(head); printf("\n==============================\nreverseRecall Linked list \n"); head = reverseRecall(head); printList(head); printf("\n==============================\nlength of Linked list: "); int len = length(head); printf("%d\n", len); printf("==============================\nRemoveHead test: \n"); RemoveHead(&head); printList(head); printf("\n==============================\nSearchMid test: "); struct node* mid; SearchMid(head, &mid); printf("%d\n", mid->data); int m = 5; struct node* elemM; printf("==============================\nSearchLastMElement2 test: "); elemM = SearchLastMElement2(head, m); printf("the last %d element is %d\n", m, elemM->data); printf("==============================\nSearchLastMElement2 test: "); elemM = SearchLastMElement2(head, m); printf("the last %d element is %d\n", m, elemM->data); return 0; }

 输出:

80 100 60 85 15 4 20
==============================
Reversed Linked list
20 4 15 85 60 100 80
==============================
reverseRecall Linked list
80 100 60 85 15 4 20
==============================
length of  Linked list: 7
==============================
RemoveHead test:
100 60 85 15 4 20
==============================
SearchMid test: 85
==============================
SearchLastMElement2 test: the last 5 element is 100
==============================
SearchLastMElement2 test: the last 5 element is 100

  

参考连接:

http://www.acmerblog.com/reverse-linked-list-5779.html

http://www.cnblogs.com/iuices/archive/2011/11/06/2238606.html

posted @ 2015-09-25 11:12  pestle  阅读(441)  评论(0编辑  收藏  举报