#include<stdio.h>
#include<stdlib.h>
#define T 1
#define F 0
typedef int Elementtype; //重命名int为Elementtype
typedef int Status; //重命名int为Status,作为函数的返回类型
struct Node //建立链表的结构体
{
Elementtype value; //链表中节点的数据域可以为各种类型(在此以整形数来代替)
struct Node *next; //链表中节点的指针区域
};
Status init(struct Node **p); //初始化头结点
Status print(struct Node *p); //将链表输出
Status lenth(struct Node *p); //计算链表的长度(在此程序中定义链表的第一个可用节点为0号位,和数组下标一样)
Status insert_head(struct Node *p, Elementtype value); //头插,新来的节点接到头结点的后面
Status insert_tail(struct Node *p, Elementtype value); //尾插,新来的节点接到链表NULL之前
Status insert_index(struct Node *p, int index, Elementtype value); //中间插,新来的节点放在下标index处
Status delete_index(struct Node *p, int index); //删除,将下标index处的节点删除(用free释放)
Status delete_value(struct Node *p, Elementtype value);//删除,将数据域为value的节点删除
Status update_index(struct Node *p, int index, Elementtype value); //修改数据,将下标index处改为value
Status update_value(struct Node *p, Elementtype old_value, Elementtype new_value); //修改数据,将老的数据old_value改为new_value
Status query_value(struct Node *p, Elementtype value);//查找value所处的下标
Status query_index(struct Node *p,int index); //查找下标index的数据(value)
Status empty(struct Node *p); //清空链表
Status destroy(struct Node **p);//销毁整个链表(释放头结点)
int main()
{
struct Node *head = NULL; //定义头结点
init(&head); //初始化头结点
int i = 0; //定义i用于循环
for(i = 0; i < 20; i++)
{
insert_head(head, i+1); //头插,i+1是为了从1开始插入数据;
insert_tail(head, i+1); //尾插
}
print(head);
delete_index(head, 2);
print(head);
insert_index(head, 2, 99);
print(head);
delete_value(head, 1);
print(head);
update_index(head, 2, 88);
print(head);
update_value(head, 3, 66);
print(head);
query_value(head, 8);
query_index(head,17);
empty(head);
print(head);
destroy(&head);
print(head);
return 0;
}
Status init(struct Node **p) //**p的原因是为了能改变头指针head的地址,head为struct Node *型,所以指向其地址的指针为 struct Node **型(当然,此函数可以将函数的返回值设为struct Node *型,将创建的头结点通过函数返回)
{
struct Node *newnode = (struct Node *)malloc(sizeof(struct Node)); //用malloc申请类型为struct Node *大小为struct Node(如果写成struct Node*就为地址的大小,不是结构体的大小)的堆空间
if(NULL == newnode)
{
return F; //空间申请不成功,返回fault
}
newnode->next = NULL; //头结点初始化
newnode->value = 0;
*p = newnode; //将newnode的地址赋给*p(head的地址此时也为newnode)
}
Status print(struct Node *p)
{
if(p == NULL) //如头指针为空则说明无此链表
{
printf("无此链表\n");
return F;
}
if(p->next == NULL) //如果头指针的下一个节点为空则说明有链表但链表无数据
{
printf("链表为空\n");
return F;
}
while(p->next != NULL) //当p->next不为空
{
printf("%4d",p->next->value); //输出p->next的数据域
p = p->next; //移动到下一个节点处,达到循环的目的
}
printf("\n");
return T;
}
Status insert_head(struct Node *p, Elementtype value) //头插,(需要知道头结点的地址,以及所插入的数据内容)
{
struct Node * new = (struct Node *)malloc(sizeof(struct Node)); //用malloc申请一个节点所需的空间
if(NULL == new) //申请的空间为NULL则说明申请不成功
{
return F;
}
new->next = NULL; //初始化新节点的指针域
new->value = value; //将所要的数据给新节点的数据域
new->next = p->next; //头插时先将新节点的指针域指向头结点的下一个节点
p->next = new; //再将头结点的指针域指向新节点(这样不会出错,如果操作步骤返了会将头结点的下一个指针域覆盖,从而使链表断开)
return T;
}
Status insert_tail(struct Node *p, Elementtype value) //尾插,(需要知道头结点的地址,以及所插入的数据内容)
{
struct Node *new = (struct Node *)malloc(sizeof(struct Node)); //用malloc申请一个节点所需的空间
if(NULL == new) //申请的空间为NULL则说明申请不成功
{
return F;
}
new->next = NULL; //初始化新节点的指针域
new->value = value; //将所要的数据给新节点的数据域
while(NULL != p->next) //遍历找到链表的结尾
{
p = p->next;
}
p->next = new; //将新节点放在尾部
}
Status insert_index(struct Node *p, int index, Elementtype value) //中间插,(需要知道头结点的地址,所插入的位置,以及数据内容)
{
int i = 0; //用于循环
struct Node *new = (struct Node *)malloc(sizeof(struct Node)); //用malloc申请一个节点所需的空间
new->next = NULL;
new->value = value;
if(index < 0 || index > lenth(p) - 1) //判断所设定的index在不在可操作范围内
{
printf("index error/n");
return F;
}
for(i = 0; i < index; i++) //找到要插入的位置
{
p = p->next;
}
new->next = p->next; //将新节点插入到index的位置上
p->next = new;
return T;
}
Status lenth(struct Node *p) //判断链表的长度
{
int len = 0; //定义一个长度
while(NULL != p->next) //遍历,记录长度
{
len++;
p = p->next;
}
return len; //将所得的长度返回
}
Status delete_index(struct Node *p, int index) //按位置删除
{
int len = 0;
int i = 0;
struct Node * temp = NULL;
len = lenth(p);
if(index < 0 || index > len-1)
{
printf("index error\n");
return F;
}
for(i = 0; i < index; i++) //找到要删除的位置
{
p = p->next;
}
temp = p->next; //将删除处的前后两个节点连接
p->next = temp->next;
free(temp); //将删除的节点释放
temp = NULL; //将temp指向空,防止野指针
return T;
}
Status delete_value(struct Node *p, Elementtype value) //按值删除
{
int flag = 0; //定义flag判断是否找到值
struct Node * temp = NULL;
while(NULL != p->next) //遍历找值
{
if(p->next->value == value)
{
temp = p->next;
p->next = temp->next;
free(temp);
temp = NULL;
flag = 1; //将值删除后,flag = 1;
}
else
{
p = p->next;
}
}
if(flag == 0) //如果flag等于0说明没找到值
{
printf("未找到value\n");
}
return T;
}
Status update_index(struct Node *p, int index, Elementtype value) //按位置修改
{
int i = 0;
if(index < 0 || index > lenth(p)-1)
{
printf("index error\n");
return F;
}
for(i = 0; i < index; i++) //找到要修改的位置
{
p = p->next;
}
p->next->value = value; //新值给旧值
return T;
}
Status update_value(struct Node *p, Elementtype old_value, Elementtype new_value) //按值删除
{
while(NULL != p->next) //遍历找值
{
if(p->next->value == old_value)
{
p->next->value = new_value; //修改
}
p = p->next;
}
return T;
}
Status query_value(struct Node *p, Elementtype value) //通过值查位置
{
int data = 0; //记录位置
while(NULL != p->next) //遍历
{
if(p->next->value == value)
{
printf("%d addr is %d\n",value,data);
}
p = p->next;
data++;
}
printf("\n");
return T;
}
Status query_index(struct Node *p,int index) //通过位置查找值
{
int i = 0;
if(index < 0 || index > lenth(p) - 1)
{
printf("index error\n");
return F;
}
for(i = 0; i < index; i++) //找位置
{
p = p->next;
}
printf("addr%d value is %d\n",index,p->next->value);
return T;
}
Status empty(struct Node *p) //清空
{
struct Node * temp = NULL;
while(p->next != NULL) //遍历删除
{
temp = p->next;
p->next = temp->next;
free(temp);
temp = NULL;
}
return T;
}
Status destroy(struct Node **p) //销毁
{
struct Node * temp = NULL;
while((*p)->next != NULL) //遍历删除
{
temp = (*p)->next;
(*p)->next = temp->next;
free(temp);
temp = NULL;
}
free(*p); //释放头结点
*p = NULL;
return T;
}