创建一个双向链表并实现增加和删除以及求表长
代码如下:
#include<string.h>
#include<stdlib.h>
#include<errno.h>
#define OK 1
#define ERROR 0
typedef struct {
char name[8];
int id;
int score;
} student;
typedef struct LNode {
student date ;
struct LNode *pre;
struct LNode *next;
} LNode, *LinkList;
主函数部分
int main(){
LinkList L;
L = ( LinkList ) malloc ( sizeof ( LinkList ) );
L -> next = NULL;
//创建链表
CreateLinkList(L);
PrintList(L);
//求表长不包括头节点
ListLen(L);
//删除元素
ListDelete(L);
PrintList(L);
//插入元素
ListInsert(L);
PrintList(L);
}
函数方法
int CreateLinkList( LinkList L )
{
char n[8];
int t, s;
LinkList p, newn;
p = L; /*尾指针指向头节点*/
FILE *r;
if ( ( r = fopen ("as.txt", "r" ) ) == NULL ) {
printf("can't open the file!!!\n");
printf("error:%s\n", strerror(errno));
exit(0);
}
while ( fscanf ( r, "%s%d%d", n, &t, &s ) != EOF ) {
newn = ( LNode * ) malloc ( sizeof ( LNode ) );
strcpy ( newn -> date.name, n );/*字符串初始化后不能直接赋值需要调用strcpy()*/
newn -> date.id = t;
newn -> date.score = s;
newn->next=NULL; /*新节点后指指针域置空*/
newn->pre=p; //新节点指向上一节点
p->next=newn; /*前一个节点指针(即原先的尾指针指向的节点)指向新节点*/
p=newn;
}
fclose(r);
L->pre=p; //头尾相连
p->next=L;
}
/*
*获取该链表的长度(不包括头结点)
*/
int ListLen(LinkList L){
LinkList p;
p=L;
int len = 0;
while(p->next!=L ){
p = p->next;
len++;
}
printf("表长为%d\n\n",len);
return len;
}
void PrintList (LinkList L) {
LinkList p;
p=L;
printf("姓名\t\t\t\t学号\t\t\t\t成绩\n");
while ( p->next!=L )/*当循环条件是p时,因为头节点数据域为空每次会输出一行乱码*/
{
printf("%s\t\t\t\t%d\t\t\t\t%d\n",p->next->date.name,p->next->date.id,p->next->date.score);
p = p -> next;
}
printf("\n");
}
int ListInsert(LinkList L )
{
LinkList p,newn;
int k,j=0;
student s;
p=L;
printf("输入要插入的节点坐标\n");
scanf("%d",&k);
while(p!=NULL&&j<k)
{
p=p->next;
j++;
}
if((j!=k)||(p==NULL))
{
printf("要插入的节点不存在");
return ERROR;
}
printf("================输入要插入的学生信息==============\n");
printf("*****姓名:"); scanf("%s",s.name);
printf("*****学号:"); scanf("%d",&s.id);
printf("*****成绩:"); scanf("%d",&s.score);
printf("输入完成\n\n");
newn=(LNode*)malloc(sizeof(LNode));
newn->date= s ;
newn->pre=p->pre; //将原先位置的节点的前指指针指向的的地址给新插入的节点的前指指针
p->pre->next=newn; //将新节点的地址给原先节点的前一个节点,新节点与前节点对接完成
newn->next=p; //新节点的后指指针指向原先节点
p->pre=newn; //原先节点的前指指针指向新插入节点,新节点与后节点对接完成
return OK;
}
int ListDelete ( LinkList L ) {
int i, j = 0;
LinkList p;
LinkList q= L;
p = L->next;
printf("输入要删除的节点位置\n");
scanf("%d", &i);
while (p->next!=L&&j<i-1)
{
p = p->next;
j++;
}
if ((j!=i-1)||(i > ListLen(q))){
printf("要删除的节点不存在\n");
return ERROR;
}
p->pre->next=p->next; //将要删除节点下一个节点地址给要删除节点前一节点的后指指针
p->next->pre=p->pre; //将要删除节点的前一个节点的地址给要删除节点的下一节点
free(p);
return OK;
}