头插法:
头插法图解:
解释:头插法顾名思义就是在头结点的后面增加结点。
首先创建一个带头结点的空的单链表head
其次按照线性表中元素的逆序依次读入数据元素,如果不是结束标志时,申请结点s,将s结点插入到头结点之后。如上图b。
#include<stdio.h> #include<stdlib.h> #include<malloc.h> typedef int elemtype; typedef struct node { elemtype data; struct node *next; }LNode *LinkList; LinkList CreatFromHead() { LinkList head; LNode *s; char c; int flag = 1;/*设置一个标识变量flag,初值为1,当输入“$”时,将flag置位0,建表结束*/ head = (LinkList)malloc(sizeof(LNode)); head->next = NULL; while(flag) { c = getchar(); if(c!='$') { s = (LinkList)malloc(sizeof(LNode)); s->data = c; s->next = head->next;/*将s插入到链表中第一个数据元素之前*/ head->next = s; } else flag = 0;/*读入的符号为"$",修改结束标识*/ } return head; }
尾插法:
尾插法图解:
解释:头插法读入的数据元素的顺序与生成的链表中数据元素的顺序是相反的。所以用尾插法就可以很好解决这个问题。因为每次都必须将新结点插入到链表的尾部,所以需要加入一个尾指针r,用来始终指向链表的尾结点,以便能够将新结点插入到链表的尾部。
#include<stdio.h> #include<stdlib.h> #include<malloc.h> typedef int elemtype; typedef struct node { elemtype data; struct node *next; }LNode *LinkList; LinkList CreatTailHead() { LinkList L; LNode *s; char c; int flag = 1;/*设置一个标识变量flag,初值为1,当输入“$”时,将flag置位0,建表结束*/ L = (LinkList)malloc(sizeof(LNode)); //为头结点分配空间 L->next = NULL; //建带头结点的空链表 r = L; //尾指针r指向表尾 while(flag) { c = getchar(); if(c!='$') { s = (LinkList)malloc(sizeof(LNode)); s->data = c; r-next = s; //插入到表尾 r = s; } else { flag = 0; r-next = NULL; } } return L; }