一.单链表
#include <stdio.h>
#include <stdlib.h>
struct node
{
unsigned char elem;
struct node *next;
};
void create_list(unsigned char elem);
void insert_node(int pos, unsigned char elem);
void delete_node(int pos);
void print_linklist(void);
int search(unsigned char elem);
struct node *head = NULL;
struct node *tail = NULL;
int main(void)
{
create_list('A');
create_list('B');
create_list('C');
create_list('D');
print_linklist();
delete_node(0);
print_linklist();
insert_node(0, 'F');
insert_node(2, 'Z');
print_linklist();
if(search('C'))
printf("the elem is found in the linklist\n");
else
printf("Can not find it\n");
return 0;
}
//这里插入采用的尾插入
void create_list(unsigned char elem)
{
struct node *p = (struct node *)malloc(sizeof(struct node)); //开辟struct node 大小的内存,让 p指针指向它
p->elem = elem;//对开辟的结构体数据部分进行元素的填充
p->next = NULL;//指针部分进行填充,让它指向0地址处
if(head == NULL) //初始化我们的头指针
head = p; //让头指针指向我们申请的第一个节点的地址
else
tail->next = p; //p节点的指针域指向我们malloc分配的新节点的地址
tail = p; //指针永远指向最后一个节点,然后它的p节点的指针域(tail->next),就可以指向我们新来的节点p
}
/*插入节点的实现思路:
比如现在1 2 3 4 5,我们要在3前面插入6,我们就要找到3的前一个节点,也就是2
让2的指针域指向6的地址,6的指针域指向3,那么我们需要遍历链表
*/
void insert_node(int pos, unsigned char elem)
{
struct node *pre;
pre = head;
int i = 0;
struct node *p = (struct node *)malloc(sizeof(struct node)); //开辟空间存放新的节点
if(pos == 0) //在头节点的地方插入
{
p->elem = elem;
p->next = head;//头指针head里面存的是第一个节点的地址,把它给我们新插入节点的指针域,
//让新插入元素的指针域,指向我们第一个节点
head = p; //把我们新插入的节点的地址给头指针,让头指针指向我们的新插入的节点
}
else
{
while(i < pos - 1) //你要找元素的位置,比你要找的元素位置少遍历1次
{
pre = pre->next; //找节点的过程就是更新pre指针的指向
i++;
}
p->elem = elem;
p->next = pre->next;//p->next指向我们的pre指针域的指向的节点
pre->next = p; //找到的元素的指针域指向我们的p节点
if(p->next == NULL) //在尾的地方插入
tail = p;
}
}
void delete_node(int pos)
{
struct node *pre, *p;
pre = head; //pre是我们要插入的节点的前节点
int i = 0;
if(pos == 0)
{
head = head->next;
free(pre);
}
else
{
while(i < pos - 1)
{
pre = pre->next;
i++;
}
p = pre->next; //要删除的p节点的地址在它前节点pre的指针域
pre->next = p->next; //让p的前节点pre的指针域指向p的后节点
if(p->next == NULL)
tail = pre;
free(p);
}
}
void print_linklist(void)
{
struct node *p;
for(p = head; p; p = p->next)
printf("%c", p->elem);
printf("\n");
}
int search(unsigned char elem)
{
struct node *p;
for(p = head; p; p = p->next)
if(p->elem == elem)
return 1;
return 0;
}
代码运行如下:
ABCD
BCD
FBZCD
the elem is found in the linklist
二.双链表
为了方便理解,一定要画图,不然指针指来指去的会很懵逼
创建链表这里我们需要好好理解,每一步怎么来的,好好理解create_list函数就行,核心就是head头指针是一直指向第一个节点的,后续增加节点是通过移动tail指针,让我们的老节点的p->next = 新节点的地址,也就是tail->next。
#include <stdio.h>
#include <stdlib.h>
struct node
{
unsigned int elem;
struct node *pre;
struct node *next;
};
struct node *head = NULL;
struct node *tail = NULL;
void create_list(unsigned int elem)
{
struct node *p = (struct node *)malloc(sizeof(struct node));
p->elem = elem;
p->pre = NULL;
p->next = NULL;
if(head == NULL) /* 指针为空,即一个节点也没有 */
head = p; /* 指向第一个节点 */
else
{
tail->next = p; /* 让我们上个节点指向下一个节点,因为我们上个节点的next就是tail-next */
p->pre = tail; /* 让pre指向前一个节点,因为tai = p(在下面), tail存的是pre前节点的地址 */
}
tail = p; /* 尾指针每次都是指向最后一个节点的 */
}
void insert_node(int pos, unsigned int elem)
{
struct node *pre;
pre = head;
int i = 0;
struct node *p = (struct node *)malloc(sizeof(struct node));
if(pos == 0)
{
p->elem = elem;
p->next = head;
head->pre = p;
p->pre = NULL;
head = p;
}
else
{
while(i < pos - 1)
{
pre = pre->next;
i++;
}
p->elem = elem;
p->pre = pre;
p->next = pre->next;
if(p->next != NULL)
pre->next->pre = p;
pre->next = p;
if(p->next == NULL)
tail = p;
}
}
void delete_node(int pos)
{
struct node *pre, *p;
pre = head;
int i = 0;
if(pos == 0)
{
head = head->next;
head->pre = NULL;
free(pre);
}
else
{
while(i < pos - 1)
{
pre = pre->next;
i++;
}
p = pre->next;
pre->next = p->next;
if(p->next != NULL)
p->next->pre = pre;
else//if(p->next == NULL)
tail = pre;
free(p);
}
}
void print_linklist(void)
{
struct node *p;
for(p = head; p; p = p->next)
printf("%5d", p->elem);
printf("\n");
}
int search(unsigned int elem)
{
struct node *p;
for(p = head; p; p = p->next)
if(p->elem == elem)
return 1;
return 0;
}
void reverse_print_linklist(void)
{
struct node *p;
for(p = tail; p; p = p->pre)
printf("%5d", p->elem);
printf("\n");
}
int main(void)
{
create_list(1);
create_list(2);
create_list(3);
create_list(4);
create_list(5);
create_list(6);
create_list(7);
print_linklist();
reverse_print_linklist();
insert_node(0, 11);
print_linklist();
delete_node(6);
print_linklist();
delete_node(0);
print_linklist();
delete_node(0);
print_linklist();
delete_node(4);
print_linklist();
insert_node(0, 8);
print_linklist();
insert_node(5, 9);
print_linklist();
insert_node(2, 13);
print_linklist();
return 0;
}
运行结果如下: