C语言 关于链表的一个程序(请高手帮忙!)

C语言 关于链表的一个程序(请高手帮忙!),第1张

//修改完了。。。。

#include<stdioh>

#include <stringh>

#include<stdlibh>

struct student{

char name[20];

char num[20];

int grade;

struct student Nextptr;

};

typedef struct student Stu;

typedef Stu St;

St creat();

main()

{

St headptr1=NULL;

St headptr2=NULL;

headptr1=creat();

//headptr2=find(&headptr1);

//print(headptr2);

//destory(headptr1,headptr2);

system("pause");

}

St creat()//建立链表1

{

St headptr1=NULL,last1=NULL,current1=NULL;

printf("Please input the information of the students:\n");

// fflush(stdin);

current1=(St) malloc(sizeof(current1));

gets(current1->name);

// fflush(stdin);

gets(current1->num);

scanf("%d",&current1->grade);

while(strcmp(current1->name,"#####")!=0)

{

if(headptr1==NULL)

{

headptr1=current1;

last1=current1;

}

else

{

last1->Nextptr=current1;

last1=current1;

}

current1=(St) malloc(sizeof(current1));

fflush(stdin);

gets(current1->name);

fflush(stdin);

gets(current1->num);

scanf("%d",&current1->grade);

}

current1->Nextptr=NULL;

return headptr1;

}

写好了,你看下

#include <stdioh>

#include <stdlibh>

#include <malloch>

typedef struct node

{

int data;

struct node next;

}Node;

void InitList(Node head);

void CreateList(Node head);

void InsertList(Node head, int key);

void DeleteList(Node head, int key);

void PrintList(Node head);

//初始化链表

void InitList(Node head)

{

(head) = (Node )malloc(sizeof(Node));

(head)->next = NULL;

}

//创建链表

void CreateList(Node head)

{

int i;

printf("您好,请输入您要插入的数据:\n");

scanf("%d", &i);

while(i != 0)

{

InsertList(head, i);

scanf("%d", &i);

}

}

//插入链表

void InsertList(Node head, int key)

{

Node p, q, s;

q = (head);

p = (head)->next;

while(p)

{

q = p;

p = p->next;

}

s = (Node )malloc(sizeof(Node));

s->data = key;

s->next = NULL;

q->next = s;

}

//删除链表

void DeleteList(Node head, int key)

{

Node p, q;

q = (head);

p = (head)->next;

while(p && p->data != key)

{

q = p;

p = p->next;

}

if(p)

{

q->next = p->next;

free(p);

p = NULL;

}

}

//输出链表

void PrintList(Node head)

{

Node p;

p = (head)->next;

while(p)

{

printf("%d\n", p->data);

p = p->next;

}

}

int main(void)

{

Node head;

int i;

InitList(&head);

CreateList(&head);

printf("删除前的数据:\n");

PrintList(&head);

printf("请输入您要删除的数据:\n");

scanf("%d", &i);

DeleteList(&head, i);

printf("删除后的数据:\n");

PrintList(&head);

return 0;

}

Makefile:

#the simplest example

OBJS = tmpo

CC = gcc

CFLAGS = -Wall -O -g

tmp: $(OBJS)

$(CC) $(OBJS) -o tmp

tmpo: tmpc

$(CC) $(CFLAGS) -c tmpc -o tmpo

clean:

rm -f o ~ tmp

您好,请输入您要插入的数据:

1 2 3 4 0

删除前的数据:

1

2

3

4

请输入您要删除的数据:

1

删除后的数据:

2

3

4

我们可以用实际的值来看看程序到底是怎么执行的。

假设你创建的链表里已经有学号为1,2,4,5的四个学生的信息。

现在我们要插入学号为3的学生的信息。

首先:

struct student insert(struct student head,struct student stu)

实参被传递过来,head是已经创建的学生信息,stu是要插入的学生信息。

struct student p0,p1,p2;

p1 = head; //让p1指向头节点

p0 = stu; //p0指向要插入的节点

if(head == NULL) //这个是检查链表是不是空的

{

head = p0; //如果是空的就把要插入的结点,设置为头指针。

p0->next = NULL;

}

else

{

while((p0->num > p1->num) && (p1->next != NULL))

{ 在这个循环里,第一次进循环的时候p0->num等于3,p1->num等于1,即3>1,而且p1后面(即p1->next)还有结点。满足条件进入第二次循环。

在进第二次循环之前需要把p1指向第2个结点,即指向学号为2的学生信息。

p2 = p1; //p2指向p1的结点 ,即头指针。

p1 = p2->next; //p1移到下一个结点,现在指向的是第2个结点。

第二次进循环的时候p0->num等于3,p1->num等于2,即3>2,而且p1后面还有结点。满足条件进入第三次循环

再次把p1移到下一个结点。

p2 = p1; 这时p2指向的是第2个结点。

p1 = p2->next; p1指向的是第3个结点。

第三次进循环的时候p0->num等于3,p1->num等于4,即3>4。不能满足条件。退出循环。

}

现在p2指向的是第2个结点,即学号为2的学生。

p1指向的是第3个结点,即学号为4的学生。

p0始终是要插入的学生。

if(p0->num <= p1->num)

{ 这里p0->num等于3,p1->num等于4,即3<4满足条件。

if(head == p1)

{ 这里p1指向的是第三个结点,所以不能满足条件。程序到下面else语句。

head = p0;

}

else

{ p2->next = p0;

到了这里p2的指针域指的是要插入的结点,即把学号为3的学生放到学号为2的学生后面。

}

p0->next = p1;

//然后这里把p1(学号为4)放到p0(学号为3)的后面。这样就连在一起了。

}

else

{

p1->next = p0;

p0->next = NULL; //把要插入的结点,设置为尾结点。

}

}

n=n+1;

return (head);

}

-----------线性表的单链表存储结构-------------

typedef struct Node{

ElemType data;

struct Node next;

} LNode, LinkList;

//----------线性表的单链表基本 *** 作------------

LinkList InitList(void); //构造一个空的线性表

void DestroyList(LinkList L);//初始条件:线性表L已存在。 *** 作结果:销毁线性表L。

LinkList MakeEmpty(LinkList L);//初始条件:线性表L已存在。 *** 作结果:将线性表L重置为空表。

int IsEmpty(LinkList L);//初始条件:线性表L已存在。 *** 作结果:判断线性表是否为空表。

int ListLength(LinkList L);//初始条件:线性表L已存在。 *** 作结果:返回线性表L结点的个数。

LNode IsLast(LinkList L); //初始条件:线性表L已存在。 *** 作结果:返回线性表L的最后一个结点(尾结点)。

LNode NewLNode(ElemType X);//构造一个数据域为X的新结点

LNode FindPrefious(ElemType X, LinkList L);//初始条件:线性表L已存在。 *** 作结果:在线性表L中寻找值为X的结点,若找到则返回该结点的前驱,否则返回NULL。

void ListDelete(LNode Pre);//初始条件:线性表L中结点P已找到。 *** 作结果:删除该结点。

void ListInsert(LNode Pre, LNode S);//初始条件:线性表L中结点P已找到,新结点S已构造。 *** 作结果:在该结点之前插入新结点X。

----------线性表的单链表基本 *** 作的算法实现------------

//我给链表设置了一个头结点,虽然它的数据域毫无意义,但它作为一个指针却意义非凡!

//它的作用我们在下面的例程中可以领教

LinkList InitList(void) //构造一个空的线性表

{

LNode Head;

Head = (LNode)malloc(sizeof(struct Node)); //为链表的头结点分配空间

if(!Head)

{

printf("Out of space!");

return NULL;

}

Head->next = NULL;

return Head;//返回头结点

}

void DestroyList(LinkList L)//初始条件:线性表L已存在。 *** 作结果:销毁线性表L。

{

LNode Head, P;

if(L)//若线性表L已存在

{

Head = L;

P = Head->next;

while(!P) //把链表中除头结点外的所有结点释放

{

free(Head);

Head = P;

P = Head->next;

}

free(Head); //释放头结点

}

}

LinkList MakeEmpty(LinkList L)//初始条件:线性表L已存在。 *** 作结果:将线性表L重置为空表。

{

LNode Head, P;

Head = L;

P = Head->next;

while(!P)//把链表中除头结点外的所有结点释放

{

free(Head);

Head = P;

P = Head->next;

}

return (Head); //返回头结点

}

int IsEmpty(LinkList L);//初始条件:线性表L已存在。 *** 作结果:判断线性表是否为空表。

{

return L->next == NULL;

}

int ListLength(LinkList L)//初始条件:线性表L已存在。 *** 作结果:返回线性表L结点的个数。

{

LNode P = L->next;

int num = 0;

while(P) //累积线性表L结点的个数

{

num++;

P = P->next;

}

return num; //返回线性表L结点的个数

}

//初始条件:线性表L已存在。 *** 作结果:返回线性表L的最后一个结点(尾结点)。

LNode IsLast(LinkList L)

{

LNode P = L->next;

if(P)

{

while(P->next) //遍历线性表L

P = P->next;

}

return P; //返回线性表L的最后一个结点,若为空表则返回NULL

}

LNode NewLNode(ElemType X)//构造一个数据域为X的新结点

{

LNode S;

S = (LNode)malloc(sizeof(struct Node))//为新结点分配空间

if(!S)

{

printf("Out of space!");

return NULL;

}

S->data = X;

S->next = NULL;

return S;//返回新结点

}

//线性表L已存在。 *** 作结果:在线性表L中寻找值为X的结点,若找到则返回该结点的前驱,否则返回NULL。

LNode FindPrefious(ElemType X, LinkList L)

{

LNode P = L;

while(P->next && P->next->data != X)//遍历链表寻找值为X的结点

P = P->next;

if(!P->next) //如果找不到值为X的结点,返回NULL

return NULL;

else //若找到则返回该结点的前驱P

return P;

}

void ListDelete(LNode Pre)//初始条件:线性表L中结点P已找到。 *** 作结果:删除该结点。

{

LNode P = Pre->next;

Pre->next = P->next;

free(P);

}

//初始条件:线性表L中结点P已找到,新结点S已构造。。 *** 作结果:在该结点之前插入新结点X。

void ListInsert(LNode Pre, LNode S)

{

S->next = Pre->next;

Pre->next = S;

}

采用头插法,j将数组a[]拆入带头结点的链表中。举例说明如下:

假设数组为int a[3]={1,2,3}; 即n3;

程序首先申请一个头结点h,对应的数据域data=0,下一节点为null;

for(i=n;i>0;i--)

{s=(JD)malloc(sizeof(JD));

s->data=a[i-1];

s->link=h->link;

h->link=s;

}

当i=3时,申请新的结点s,s->data=a[2]=3; s->link=h->link=null; h->link=s;

即现在链表如下 h,3;

当i=2时,申请新的结点s,s->data=a[1]=2; s->link=h->link=3; h->link=s;

即现在链表如下 h,2,3;

当i=1时,申请新的结点s,s->data=a[0]=1; s->link=h->link=2; h->link=s;

即现在链表如下 h,1,2,3;

所以最后插入的结果为:h a[0] a[1] a[2]

前阵子做的用单向链表实现约瑟夫问题:

有M个人围一圈玩报数,凡报到N的出退出,输出每次退出的人的编号。

#include "stdioh"

struct game

{

int ID;

game pNext;

};

void main()

{

int i,m=17,n=3;

game pPrev,pNode,pTop;

printf("Input M N:");

scanf("%d %d",&m,&n);

if(n>m||n<1) return;

pTop=new game;

pTop->ID=1;

pPrev=pTop;

for(i=2;i<=m;i++)

{

pNode=new game;

pNode->ID=i;

pPrev->pNext=pNode;

pPrev=pNode;

}

pNode->pNext=pTop;

pPrev=pNode;

pNode=pTop;

i=0;

while(pNode->pNext!=pNode)

{

i++;

if(i%n==0)

{

printf("%d ",pNode->ID);

pPrev->pNext=pNode->pNext;

delete pNode;

pNode=pPrev->pNext;

i=0;

}

else

{

pPrev=pNode;

pNode=pNode->pNext;

}

}

delete pNode;

}

以上就是关于C语言 关于链表的一个程序(请高手帮忙!)全部的内容,包括:C语言 关于链表的一个程序(请高手帮忙!)、50分求用c语言编写链表程序、编写一个简单的C语言链表插入程序!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10034832.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-04
下一篇 2023-05-04

发表评论

登录后才能评论

评论列表(0条)

保存