实现以下操作
init 初始化
traverse 遍历
head_add 头追加(),尾追加(尾插法)只需要注释掉函数最后一行的头指针赋值
len 长度
insert 指定位置插入
search 正、反向查找数据,返回第1次匹配的位置,找不到返回-1
get 获取指定位置的数据
代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct node {
int data;
struct node *pNext;
}NODE, *PNODE;
void init(PNODE *);
void traverse(PNODE);
void head_add(PNODE *, int);
int len(PNODE);
bool insert(PNODE *, int, int);
int search(PNODE, int, bool);
bool get(PNODE, int, int *);
bool get(PNODE head, int pos, int *pVal)
{
PNODE p = head;
int i = 1;
if (! head || pos < 1 || pos > len(head)) {
return false;
}
while (i < pos) {
p = p->pNext;
++i;
}
*pVal = p->data;
return true;
}
int search(PNODE head, int val, bool forward)
{
PNODE p = head;
int i = 1, last = -1;
if (!head)
return -1;
if (forward) {
while (p->pNext != head && p->data != val) {
p = p->pNext;
++i;
}
if (p->data == val)
last = i;
}
else {
while (p->pNext != head) {
if (p->data == val) {
last = i;
}
p = p->pNext;
++i;
}
if (p->data == val)
last = i;
}
return last;
}
bool insert(PNODE *pHead, int pos, int val)
{
PNODE tmp, p;
int i = 1;
printf("尝试插入位置 %d 数值 %d: ", pos, val);
if (pos < 1 || pos > len(*pHead)+1) {
printf(" 无效的插入位置\n");
return false;
}
tmp = (PNODE)malloc(sizeof(NODE));
tmp->data = val;
if (! *pHead) {
*pHead = tmp;
tmp->pNext = *pHead;
printf(", 空链表的第1个节点");
}
else if (pos == 1) {
p = (*pHead)->pNext;
while (p->pNext != (*pHead)) {
p = p->pNext;
}
p->pNext = tmp;
tmp->pNext = *pHead;
// 更新头指针指向(不加下面这行则实现了尾插法)
*pHead = tmp;
}
else {
p = *pHead;
while (i < pos-1) {
p = p->pNext;
i++;
}
tmp->pNext = p->pNext;
p->pNext = tmp;
}
printf(", 成功\n");
return true;
}
int len(PNODE head)
{
PNODE p = head;
int i = 1;
if (!head)
return 0;
while (p->pNext != head) {
p = p->pNext;
++i;
}
return i;
}
void head_add(PNODE *pHead, int val)
{
printf("head_add node value: %d\n", val);
PNODE tmp, p;
if (*pHead == NULL) {
*pHead = (PNODE)malloc(sizeof(NODE));
if (! *pHead) {
printf("内存分配失败!\n");
return;
}
(*pHead)->data = val;
(*pHead)->pNext = *pHead;
}
else {
tmp = (PNODE)malloc(sizeof(NODE));
if (! tmp) {
printf("内存分配失败!\n");
return;
}
tmp->data = val;
p = (*pHead)->pNext;
while (p->pNext != (*pHead)) {
p = p->pNext;
}
p->pNext = tmp;
tmp->pNext = *pHead;
// 更新头指针指向(不加下面这行则实现了尾插法)
*pHead = tmp;
}
}
void traverse(PNODE head)
{
printf("遍历结果:\n");
PNODE p = head;
int i = 1;
if (! head) {
printf("链表为空!\n");
return;
}
do {
printf("第 %d 个节点, self %p, data %d, pNext %p\n", i, p, p->data, p->pNext);
p = p->pNext;
++i;
} while (p != head);
}
void init(PNODE *pHead)
{
PNODE tmp, p;
int val, i=1;
while (1) {
printf("请输入节点 %d 的值,结束初始化请输入负数: ", i);
scanf("%d", &val);
if (val < 0)
break;
if (*pHead == NULL) {
*pHead = (PNODE)malloc(sizeof(NODE));
if (! *pHead) {
printf("内存分配失败!\n");
return;
}
(*pHead)->data = val;
(*pHead)->pNext = *pHead;
printf("初始化头节点:self %p, data %d, pNext %p\n", *pHead, (*pHead)->data, (*pHead)->pNext);
}
else {
tmp = (PNODE)malloc(sizeof(NODE));
if (! tmp) {
printf("内存分配失败!\n");
return;
}
tmp->data = val;
tmp->pNext = *pHead;
p = (*pHead)->pNext;
while (p->pNext != (*pHead)) {
p = p->pNext;
}
p->pNext = tmp;
}
++i;
}
}
int main(void)
{
PNODE head;
int val;
traverse(head);
printf("len:%d\n", len(head));
init(&head);
traverse(head);
head_add(&head, 10);
head_add(&head, 9);
traverse(head);
printf("len:%d\n", len(head));
insert(&head, 1, 8);
insert(&head, 1, 6);
insert(&head, 2, 7);
traverse(head);
printf("len:%d\n", len(head));
insert(&head, 2, 11);
traverse(head);
printf("正向查找 5 所在节点:%d\n", search(head, 5, true));
printf("正向查找 11 所在节点:%d\n", search(head, 11, true));
printf("反向查找 11 所在节点:%d\n", search(head, 11, false));
printf("正向查找 13 所在节点:%d\n", search(head, 13, true));
if (get(head, 1, &val)) {
printf("get成功,第 %d 节点值为: %d\n", 1, val);
}
if (get(head, 5, &val)) {
printf("get成功,第 %d 节点值为: %d\n", 5, val);
}
return 0;
}
output
[root@8be225462e66 c]# gcc circular_linklist.c && ./a.out
遍历结果:
链表为空!
len:0
请输入节点 1 的值,结束初始化请输入负数: 11
初始化头节点:self 0x139cac0, data 11, pNext 0x139cac0
请输入节点 2 的值,结束初始化请输入负数: 12
请输入节点 3 的值,结束初始化请输入负数: 13
请输入节点 4 的值,结束初始化请输入负数: -1
遍历结果:
第 1 个节点, self 0x139cac0, data 11, pNext 0x139cae0
第 2 个节点, self 0x139cae0, data 12, pNext 0x139cb00
第 3 个节点, self 0x139cb00, data 13, pNext 0x139cac0
head_add node value: 10
head_add node value: 9
遍历结果:
第 1 个节点, self 0x139cb40, data 9, pNext 0x139cb20
第 2 个节点, self 0x139cb20, data 10, pNext 0x139cac0
第 3 个节点, self 0x139cac0, data 11, pNext 0x139cae0
第 4 个节点, self 0x139cae0, data 12, pNext 0x139cb00
第 5 个节点, self 0x139cb00, data 13, pNext 0x139cb40
len:5
尝试插入位置 1 数值 8: , 成功
尝试插入位置 1 数值 6: , 成功
尝试插入位置 2 数值 7: , 成功
遍历结果:
第 1 个节点, self 0x139cb80, data 6, pNext 0x139cba0
第 2 个节点, self 0x139cba0, data 7, pNext 0x139cb60
第 3 个节点, self 0x139cb60, data 8, pNext 0x139cb40
第 4 个节点, self 0x139cb40, data 9, pNext 0x139cb20
第 5 个节点, self 0x139cb20, data 10, pNext 0x139cac0
第 6 个节点, self 0x139cac0, data 11, pNext 0x139cae0
第 7 个节点, self 0x139cae0, data 12, pNext 0x139cb00
第 8 个节点, self 0x139cb00, data 13, pNext 0x139cb80
len:8
尝试插入位置 2 数值 11: , 成功
遍历结果:
第 1 个节点, self 0x139cb80, data 6, pNext 0x139cbc0
第 2 个节点, self 0x139cbc0, data 11, pNext 0x139cba0
第 3 个节点, self 0x139cba0, data 7, pNext 0x139cb60
第 4 个节点, self 0x139cb60, data 8, pNext 0x139cb40
第 5 个节点, self 0x139cb40, data 9, pNext 0x139cb20
第 6 个节点, self 0x139cb20, data 10, pNext 0x139cac0
第 7 个节点, self 0x139cac0, data 11, pNext 0x139cae0
第 8 个节点, self 0x139cae0, data 12, pNext 0x139cb00
第 9 个节点, self 0x139cb00, data 13, pNext 0x139cb80
正向查找 5 所在节点:-1
正向查找 11 所在节点:2
反向查找 11 所在节点:7
正向查找 13 所在节点:9
get成功,第 1 节点值为: 6
get成功,第 5 节点值为: 9
[root@8be225462e66 c]#