C++面试题中很大一个板块——数据结构,主要包括线性表、栈、队列、字符串、二叉树等等,今天我们先来说说单链表。
一、概念
单链表(singly linked list)是一种最简单的链表表示,也叫做线性链表。单链表的一个存储结点(node)包含两个部分data和link。data部分称为数据域,用于存储线性表的一个数据元素。link部分称为指针域或链域,用于存放一个指针,该指针指示该链表中下一个结点的开始存储地址。
二、存储结构
typedef struct Node
{
ElemType data;
struct Node *next;
}Node;
三、初始化单链表
void Init_LinkList(Node *l)
{
l = (Node*)malloc(sizeof(Node));
l->next = NULL;
}
四、建立单链表
头插法建立单链表:
从一个空表开始,重复读入数据,生成新结点,将读入的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头结点之后,直至读入结束标志为止。
void CreateLinkList_Head(Node* node)
{
Node *s;
int elem;
bool flag = true;
//flag为false,建表结束
while(flag)
{
printf("Please input the data:");
scanf("%d", &elem);
if(elem != 0)
{
//建立新结点
s=(Node*)malloc(sizeof(Node));
s->data = elem;
//将s结点插入表头
s->next = node->next;
node->next = s;
}else
{
flag = false;
}
}
}
尾插法建立单链表:
void CreateLinkList_Tail(Node* node)
{
Node *s, *r;
int elem;
bool flag = true;
r = node;
//flag为false,建表结束
while(flag)
{
printf("Please input the data:");
scanf("%d", &elem);
if(elem != 0)
{
//建立新结点
s=(Node*)malloc(sizeof(Node));
s->data = elem;
//将s结点插入尾
r->next = s;
r = s;
}else
{
flag = false;
r->next = NULL;
}
}
}
五、计算单链表长度
int Length_LinkList(Node* node)
{
int len = 0;
Node *p;
p = node;
if(node != NULL)
{
p = p->next;
}
while(p != NULL)
{
p = p->next;
len++;
}
return len;
}
六、打印单链表
void Print_LinkList(Node* node)
{
Node *p;
int len;
len = Length_LinkList(node);
p = node;
if(node != NULL)
{
p = p->next;
}
while(p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
七、查找单链表
按序号查找:
设带头结点的单链表的长度为n,要查找表中第index个结点,从单链表的头指针noda出发,从头结点(noda->next)开始遍历一遍链表,用j 做记数器,当j=index时,指针p所指的结点就是要找的第index个结点。
Node* Find_LinkList(Node* node, int index)
{
int j = 0;
Node *p;
p = node;
while((p->next != NULL) && (j < (index-1)))
{
p = p->next;
j++;
}
if(j == (index-1))
{
return p;
}else
{
return NULL;
}
}
按值查找:
在单链表中查找是否有结点值等于key的结点,若有的话,则返回首次找到其值为key的结点的存储位置,否则返回NULL。
Node* Find_LinkList(Node* node, int key)
{
Node *p;
p = node->next;
while(p != NULL)
{
if(p->data != key)
{
p = p->next;
}else
{
break;
}
}
return p;
}
八、单链表插入元素
在头结点的单链表node中第index个数据元素之前插入一个数据元素elem,需要首先在单链表中找到第index-1个结点并由指针p指示,然后申请一个新的结点并由指针s指示,其数据域的值为elem,并修改第index-1个结点的指针使其指向s,然后使s结点的指针域指向第index个结点。
bool Insert_LinkList(Node *node, int index, int elem)
{
Node *p,*s;
int k = 0;
p = node;
while((p != NULL) && (k < index-1))
{
p = p->next;
k++;
}
if(!p)
{
return false;
}
s = (Node*)malloc(sizeof(Node));
s->data = elem;
s->next = p->next;
p->next = s;
return true;
}
九、单链表删除元素
在带头结点的单链表node中删除第index个结点,先找出第index-1个结点并使p指向第index-1个结点,而后删除第index个结点并释放结点空间。
bool Delete_LinkList(Node *node, int index, int *elem)
{
Node *p,*s;
int k = 0;
p = node;
while((p != NULL) && (k < index-1))
{
p = p->next;
k++;
}
if(!(p->next))
{
return false;
}
s = p->next;
p->next = p->next->next;
*elem = s->data;
free(s);
return true;
}