单链表
线性表的顺序存储结构的特色是逻辑关系上相邻的两个元素在物理位置上也相邻,所以能够随机存取表中任一元素。然而,这个特色也致使了这种存储结构的缺点:在进行插入或删除元素时,须要移动大量的元素。而链式存储结构不要求逻辑上相邻的元素在物理位置上也相邻,所以它没有顺序存储结构的缺点,但同时也失去了顺序表可随机存取的优势。node
线性表的链式存储结构的特色是用一组任意的存储单元存储线性表的数据元素(这组存储单元能够是连续的,也能够是不连续的)。所以,为了表示每一个数据元素与其直接后继数据元素之间的逻辑关系,对于一个数据元素来讲,除了存储其自己的信息外,还需存储一个指示其直接后继的信息(即直接后继的存储位置),这两部分信息的组合称为一个结点。它包括两部分:其中存储数据元素信息的部分称为数据域,存储直接后继存储位置的部分称为指针域。指针域中存储的信息称做指针或链。注意,这里讨论的链表的每一个结点中只包含一个指针域,故又称为线性链表或单链表。函数
为方便实现,为每一个链表加上一个附加头结点,它位于链表第一个元素结点以前。附加头结点的数据域能够不存储任何信息,也能够存放一个特殊标志或表长。spa
#include
#include
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int boolean;
typedef int Elemtype;
typedef struct LNode {
Elemtype data; // 数据域
struct LNode* link; // 指针域
} LNode;
LNode* initNode();
// 初始化单链表结点
void Input_pre(LNode* first, Elemtype endTag);
// 头插法创建单链表
void Input_last(LNode* first, Elemtype endTag);
// 尾插法创建单链表
void Output(LNode* first);
// 输出单链表
void makeEmpty(LNode* first);
// 将链表置成空表
int getLength(LNode* first);
// 计算带附加头结点的单链表的长度
LNode* Search(LNode* first, Elemtype e);
// 在表中搜索含数据e的结点,搜索成功时返回该结点地址,不然返回NULL
LNode* Locate(LNode* first, int i);
// 定位函数,返回表中第i个元素的地址,若i < 0或i超出表中结点个数,则返回NULL
boolean getData(LNode* first, int i, Elemtype* e);
// 取出链表中第i个元素的值
boolean setData(LNode* first, int i, Elemtype e);
// 给链表中第i个元素赋值e
boolean Insert(LNode* first, int i, Elemtype e);
// 在带头结点的单链表中第i个位置以前插入元素e
boolean Delete(LNode* first, int i, Elemtype* e);
// 在带头结点的单链表中删除第i个元素,并由e返回其值
boolean Append(LNode* first, Elemtype e);
// 在单链表的表尾插入一个元素
LNode* initNode() {
LNode* node = (LNode*)malloc(sizeof(LNode));
if(node == NULL) {
printf("存储分配错误!\n");
exit(INFEASIBLE);
}
node->data = 0;
node->link = NULL;
}
void makeEmpty(LNode* first) {
LNode* q;
while(first->link != NULL) {
q = first->link;
first->link = q->link;
free(q);
}
}
void Input_pre(LNode* first, Elemtype endTag) { // endTag是输入结束的标志
LNode* newNode;
int data;
makeEmpty(first);
scanf("%d", &data);
while(data != endTag) {
newNode = (LNode*)malloc(sizeof(LNode));
newNode->data = data;
if(newNode == NULL) {
printf("存储分配错误!\n");
exit(INFEASIBLE);
}
if(first->link != NULL) {
newNode->link = first->link;
first->link = newNode;
} else {
first->link = newNode;
newNode->link = NULL;
}
scanf("%d", &data);
}
}
void Input_last(LNode* first, Elemtype endTag) { // endTag是输入结束的标志
LNode* newNode;
LNode* last; // 尾指针
int data;
makeEmpty(first);
scanf("%d", &data);
last = first;
while(data != endTag) {
newNode = (LNode*)malloc(sizeof(LNode));
newNode->data = data;
if(newNode == NULL) {
printf("存储分配错误!\n");
exit(INFEASIBLE);
}
last->link = newNode;
last = newNode;
scanf("%d", &data);
}
last->link = NULL;
}
void Output(LNode* first) {
LNode* current = first->link;
while(current != NULL) {
printf("%d ", current->data);
current = current->link;
}
printf("\n");
}
int getLength(LNode* first) {
LNode* current = first->link;
int counter = 0;
while(current != NULL) {
current = current->link;
counter++;
}
return counter;
}
LNode* Search(LNode* first, Elemtype e) {
LNode* current = first->link;
while(current != NULL) {
if(current->data == e)
break;
else
current = current->link;
}
return current;
}
LNode* Locate(LNode* first, int i) {
if(i < 0 || i > getLength(first)) {
return NULL;
}
LNode* current = first;
int k = 0;
while(current != NULL && k < i) {
current = current->link;
k++;
}
return current;
}
boolean getData(LNode* first, int i, Elemtype* e) {
if(i < 0 || i > getLength(first)) {
return ERROR;
}
LNode* current = Locate(first, i);
*e = current->data;
return OK;
}
boolean setData(LNode* first, int i, Elemtype e) {
if(i < 0 || i > getLength(first)) {
return ERROR;
}
LNode* current = Locate(first, i);
current->data = e;
return OK;
}
boolean Insert(LNode* first, int i, Elemtype e) {
LNode* current = Locate(first, i - 1);
if(current == NULL) {
return FALSE;
}
LNode* newNode = (LNode*)malloc(sizeof(LNode));
if(newNode == NULL) {
printf("存储分配错误!\n");
exit(INFEASIBLE);
}
newNode->data = e;
newNode->link = current->link;
current->link = newNode;
return OK;
}
boolean Delete(LNode* first, int i, Elemtype* e) {
LNode* current = Locate(first, i - 1);
if(current == NULL || current->link == NULL) { // 头结点不能删除,限制current->link != NULL
return ERROR;
}
LNode* del = current->link;
current->link = del->link;
*e = del->data;
free(del);
return OK;
}
boolean Append(LNode* first, Elemtype e) {
LNode* newNode = initNode();
newNode->data = e;
LNode* current = first->link;
while(current->link != NULL) {
current = current->link;
}
current->link = newNode;
return OK;
}
int main(int argc, char* argv[]) {
LNode* first = initNode();
printf("请输入要插入单链表中的元素,输入0时结束:\n");
Input_last(first, 0);
printf("单链表中的元素为:\n");
Output(first);
return 0;
}