1.单链表的建立可以采取头插法和尾插法,其中头插法的输入顺序与逻辑顺序正好相反的,尾插法可以解决这个问题。
1)头插法:
- 先创建一个只有头结点的空单链表。
- 重复读入数据,并生成新节点。
- 将新节点总是插入到头结点之后,直到读入结束标志为止。
参见图:
2) 尾插法:
总是将新节点插入到当前链表的表尾,为此需要增加一个尾指针,记录当前链表尾节点的地址。
参见图:
3) 在单链表的尾部插入一个元素,其中需要注意的是要记录链表的头结点位置,便于输出,还有就是判断这个单链表是否为空,增加相关处理机制。
参考代码如下:
#include "stdafx.h" #include <iostream> using namespace std; typedef struct pList { int value; pList* next; }LinkList; LinkList* createList_H(); LinkList * createList_R(); LinkList *addTail(LinkList *phead, int tailValue); void print( const LinkList * head) { head = head->next; while (head!=NULL) { cout << head->value << " "; head = head->next; } cout << endl; } int main(int argc, char* argv[]) { LinkList *head; //head = createList_H(); head= createList_R(); cout << "采用尾插法简历链表并打印:" << endl; print(head); head=addTail(head, 5); cout << "在链表尾部插入5 并打印:" << endl; print(head); return 0; } //头插法 LinkList* createList_H() { LinkList *H , *temp; int s; H = new LinkList(); while (cin >> s) { temp = new LinkList(); temp->value = s; temp->next = H->next; H->next = temp; } return H; } //尾插法 LinkList * createList_R() { LinkList * H, *R, *P; int s; H = new LinkList(); R = H; while (cin>>s) { P = new LinkList(); P->value = s; R->next = P; R = P; } return H; } LinkList *addTail(LinkList *phead, int tailValue) { //对要插入的值放到一个新的结点上去 LinkList * pnew, *pnode; pnew= new LinkList(); pnew->value=tailValue; pnode = phead; //对头结点 phead进行保存。 //分两种情况:头结点为NULL,或者其它 if (NULL==phead) phead=pnew; else { while (phead->next != NULL) phead = phead->next; phead->next = pnew; } return pnode; }
一些tips:
new相对于malloc在进行内存申请的时候,会自动进行初始化,如上面pnew= new LinkList(); 会自动将pnew->value=0,pnew->next=NULL。
头插法和尾插法的时间效率是一样的,都是O(n).
尾插法动画:http://www.nowamagic.net/librarys/veda/detail/1811