您的位置:首页 > 理论基础 > 数据结构算法

数据结构——单链表(C语言实现)

2017-07-12 21:53 423 查看

单链表

       线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素。然而,这个特点也导致了这种存储结构的缺点:在进行插入或删除元素时,需要移动大量的元素。而链式存储结构不要求逻辑上相邻的元素在物理位置上也相邻,因此它没有顺序存储结构的缺点,但同时也失去了顺序表可随机存取的优点。

       线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。因此,为了表示每个数据元素与其直接后继数据元素之间的逻辑关系,对于一个数据元素来说,除了存储其本身的信息外,还需存储一个指示其直接后继的信息(即直接后继的存储位置),这两部分信息的组合称为一个结点。它包括两部分:其中存储数据元素信息的部分称为数据域,存储直接后继存储位置的部分称为指针域。指针域中存储的信息称作指针或链。注意,这里讨论的链表的每个结点中只包含一个指针域,故又称为线性链表单链表

       为方便实现,为每个链表加上一个附加头结点,它位于链表第一个元素结点之前。附加头结点的数据域可以不存储任何信息,也可以存放一个特殊标志或表长。

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

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: