算法初步——链表
在我们储存一大波数据时,我们通常使用数组,但数组在储存器中进行储存的时候需要一整段连续的储存空间,这无疑是对储存空间的浪费。并且我们在对数组数据进行利用时我们总要修改很多数据,例如:我们在数组中插入一个数据的时候,我们需要将插入位置以后的所有数据的位置全部后移一个空间,这样我们才能成功的将数据插入进那个空位中。我们对这个算法进行时间复杂度分析,我们很容易发现这个算法的时间复杂度为O(n)。但当我们在使用链表时我们只需要增加一段逻辑结构就可以将目标数据插入其中,而其他的数据不需要进行改变。
下面我们就来实现链表的使用。
我们的链表是由一个一个的结点构成的,而每一个节点均包含两部分——数据域和指针域。数据域用来存储节点的数据,指针域用来存储下一个节点的地址。我们首先定义一个结构体类型来储存这个结点:
struct node { int data; struct node* next; };
上面代码中,我们定义了一个叫做node的结构体类型,分别存放了结点的数据域与指针域。
下面我们开始创建链表:我们需要一链表的头节点head,当我们链表为空时,头节点的指针也为空,并用指针q指向第一个结点
struct node* head; head->next = NULL; q = head;
现在我们开始创建第一个节点,并用工作指针指向这个节点:
struct node* p; p = (struct node*)malloc(sizeof(struct node));
接着我们创建该结点的数据域和指针域:
cin >> a; p->data = a; p->next = NULL; q->next = p; q = p;
这样经过数次循环我们即可创建出一个链表。
完整代码如下:
#include<iostream> using namespace std; struct node { int data; struct node* next; }; int main() { int n, a; cin >> n; struct node* head, * p, * q; head = (struct node*)malloc(sizeof(struct node)); head->next = NULL; q = head; for (int i = 1; i <= n; i++) { p = (struct node*)malloc(sizeof(struct node)); cin >> a; p->data = a; p->next = NULL; q->next = p; q = p; } struct node* tail; tail = head->next; while (tail != NULL) { cout << tail->data << " "; tail = tail->next; } cout << endl; return 0; }
这样我么就可以完成本节开头的那个问题:将数据插入进有序链表中,代码如下:
#include<iostream> using namespace std; struct node { int data; struct node* next; }; int main() { int n, a; cin >> n; struct node* head, * p, * q; head = (struct node*)malloc(sizeof(struct node)); head->next = NULL; q = head; for (int i = 1; i <= n; i++) { p = (struct node*)malloc(sizeof(struct node)); cin >> a; p->data = a; p->next = NULL; q->next = p; q = p; } cin >> a; struct node* tail; tail = head->next; while (tail) { if (tail->next == NULL || tail->next->data > a) { p = (struct node*)malloc(sizeof(struct node)); p->data = a; p->next = tail->next; tail->next = p; break; } tail = tail->next; } tail = head->next; while (tail != NULL) { cout << tail->data << " "; tail = tail->next; } cout << endl; return 0; }
这样我们就完成了链表的简单应用,可以自己动手试一下^_^