C语言中数据结构中的单向链表的问题;

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言中数据结构中的单向链表的问题;相关的知识,希望对你有一定的参考价值。

1、设线性表采用带表头附加结点的单链表存储结构,请编写线性表抽象数据类型各基本操作的实现函数,并存放在头文件LinkList.h中(注:教材上为不带表头附加结点)。同时建立一个验证操作实现的主函数文件test5.cpp,编译并调试程序,直到正确运行。
⑴ 单向链表的存储结构可定义如下:
struct LNode // 定义单链表节点类型
ElemType data; // 存放结点中的数据信息
LNode *next; // 指示下一个结点地址的指针

⑵ 线性表基本操作可包括如下一些:
① void InitList (LNode *&H) //初始化单链表
② void ClearList(LNode *&H) //清除单链表
③ int LengthList (LNode *H) //求单链表长度
④ bool EmptyList (LNode *H) //判断单链表是否为空表
⑤ ElemType GetList (LNode *H, int pos)
//取单链表第 pos 位置上的元素
⑥ void TraverseList(LNode *H) //遍历单链表
⑦ bool InsertList ( LNode *&H, ElemType item, int pos)
//向单链表插入一个元素
⑧ bool DeleteList ( LNode *&H, ElemType &item, int pos)
//从单链表中删除一个元素
⑶ 带表头附加结点的单链表初始化操作的实现可参考如下:
void InitList(LNode *&H)
//构造一个空的线性链表H,即为链表设置一个头结点,
//头结点的data数据域不赋任何值,头结点的指针域next则为空
H=(LNode *)malloc(sizeof(LNode)); // 产生头结点H
if (!H) exit(0); // 存储分配失败,退出系统
H->next=NULL; // 指针域为空

#include "stdlib.h"
#include "stdio.h"

//链表的类型定义
typedef struct node

int data; //值域
struct node *link; //指针域
*PNode,*LinkList;
//typedef struct node *PNode;
//typedef struct node *LinkList;

//创建空链表
LinkList createNullist_link(void)

LinkList list=(LinkList)malloc(sizeof(struct node));//申请表头结点空间
if(list!=NULL) list->link=NULL;
else printf("Out of space!\n");//创建失败
return(list);


//判断空链表
int isNullist_linkq(LinkList list)

return(list->link==NULL);


//在单链表中求某元素的存储位置
PNode locate_link(LinkList list,int x)
//在list 带有头结点的单链表中找第一个值为x的结点存储位置
PNode p;
if(list->link==NULL) return(NULL);
p=list->link;
while(p!=NULL && p->data!=x) p=p->link;
return(p);


// 单链表的插入
int insertPost_link(LinkList list,PNode p,int x)
//在list 带有头结点的单链表中,p所指结点后面插入元素x
PNode q=(PNode )malloc(sizeof(struct node));
if(q==NULL)

printf("Out of space!!!\n");
return(0);

else

q->data=x;
q->link=p->link;
p->link=q;
return(1);



// 在单链表求p所指结点的前驱结点
PNode locatePre_link(LinkList list,PNode p)

PNode p1;
if(list->link==NULL) return(NULL);
while(p1!=NULL && p1->link!=p) p1=p1->link;
return(p1);


// 单链表的删除
int insertPost_link(LinkList list,int x)
//在list 带有头结点的单链表中删除第一个值为x的结点
PNode p,q ;
p=list;
if(p->link==NULL) return(0);
while(p->link!=NULL && p->link->data!=x)
p=p->link;//找值为x的结点的前驱结点的存储位置
if(p->link==NULL) //没找到值为x的结点

printf("Not exist!\n");
return(0);

else

q=p->link;
p->link=q->link;
free(q);
return(1);



void main()

int i,x;
PNode p;
LinkList list1;
list1=createNullist_link();
if(list1!=NULL)
printf("创建空表成功!\n");
p=list1;
for(i=0;i<5;i++)

printf("请输入第 %d 个结点的值:",i+1);
scanf("%d",&x);
insertPost_link(list1,p,x);
p=p->link;

printf("\n");
p=list1->link;
while(p!=NULL)

if(p->link==NULL)
printf("%d",p->data);
else
printf("%d->",p->data);
p=p->link;

printf("\n");
printf("请输入删除结点的值:",i+1);
scanf("%d",&x);
insertPost_link(list1,x);
printf("\n");
p=list1->link;
while(p!=NULL)

if(p->link==NULL)
printf("%d",p->data);
else
printf("%d->",p->data);
p=p->link;


参考技术A #include <stdio.h>
#include <windows.h>

typedef struct node

int num;
struct node *next;
lnode;

lnode *creat()

lnode *head,*p,*q;
int n;

head=NULL;

printf("输入要创建的节点数\n");
scanf("%d",&n);
while(n)

p=(lnode *)malloc(sizeof(lnode));
printf("输入数据\n");
scanf("%d",&p->num);
if (head==NULL)

head=q=p;

else

q->next=p;
q=p;

n--;

q->next=NULL;
return head;


lnode *insert(lnode *head)

lnode *p,*q,*s;
int n;
char ch;

q=p=head;

printf("输入插入的位置\n");
scanf("%d",&n);
printf("请选择是插入在前还是在后(F or B)\n");
getchar();
ch=getchar();
if(ch=='F'||ch=='f')

s=(lnode *)malloc(sizeof(lnode));
printf("请输入数据\n");
scanf("%d",&s->num);
while(p&&--n)

q=p;
p=p->next;

if (q==p)

s->next=q;
return s;

else

q->next=s;
s->next=p;
return head;


else if (ch=='B'||ch=='b')

s=(lnode *)malloc(sizeof(lnode));
printf("请输入数据\n");
scanf("%d",&s->num);
while(p&&n--)

q=p;
p=p->next;

if (NULL==q->next)

q->next=s;
s->next=NULL;
return head;

else

q->next=s;
s->next=p;
return head;


else

printf("输入错误\n");



lnode *del(lnode *head)

lnode *p,*q;
int n;
int flag=0;

p=q=head;
printf("请输入删除的数据\n");
scanf("%d",&n);
while(p)


if (p->num==n)

flag=1;
if (head==p)

head=head->next;


else if(NULL==p->next)

q->next=NULL;


else

q->next=p->next;



q=p;
p=p->next;

if (flag==0)

printf("没有找到数据\n");
system("pause");

else

printf("删除成功\n");
system("pause");

return head;


lnode *sort(lnode *head)

lnode *t,*f,*min,*p_min,*s;
char ch;

f=NULL;

printf("请输入排序方式:升序(A/a),降序(D/d)\n");
getchar();
ch=getchar();
if (ch=='A'||ch=='a')

while(NULL!=head)

for (min=head,s=head;s->next!=NULL;s=s->next)

if (min->num>s->next->num)

p_min=s;
min=s->next;



if (NULL==f)

f=min;
t=min;

else

t->next=min;
t=min;

if (min==head)

head=head->next;

else

p_min->next=min->next;


if (f!=NULL)

t->next=NULL;

printf("排序完成\n");
system("pause");
head=f;
return f;

else if (ch=='D'||ch=='d')

while(NULL!=head)

for (min=head,s=head;s->next!=NULL;s=s->next)

if (min->num<s->next->num)

p_min=s;
min=s->next;



if (NULL==f)

f=min;
t=min;

else

t->next=min;
t=min;

if (min==head)

head=head->next;

else

p_min->next=min->next;


if (f!=NULL)

t->next=NULL;


printf("排序完成\n");
system("pause");
head=f;
return f;




void dispaly(lnode *head)

lnode *p;

p=head;

printf("\n");
while(p!=NULL)

printf("%d\t",p->num);
p=p->next;



int getoption()

int n;

printf("0 退出\n");
printf("1 创建链表\n");
printf("2 插入节点\n");
printf("3 删除节点\n");
printf("4 排序节点\n");
printf("5 显示链表\n");
printf("请选择操作\t");
scanf("%d",&n);
return n;


int main()

lnode *temp;
char ch;
int o;

do

system("cls");
o=getoption();
switch (o)

case 0:
exit(0);
break;
case 1 :
system("cls");
temp=creat();
break;
case 2:
system("cls");
temp=insert(temp);
break;
case 3:
system("cls");
temp=del(temp);
break;
case 4:
system("cls");
temp=sort(temp);
break;
case 5:
system("cls");
dispaly(temp);
system("pause");
break;


system("cls");
printf("按0退出,任意键继续\t");
ch=getchar();
if (ch=='0')

exit(0);

while (ch!='0');
参考技术B 有什么问题?不会要别人帮你写复杂程序吧? 参考技术C 我也在学,加油啊

单向链表的简单实现

一、概念

  单向链表是一种简单数据结构,由多个节点构成,每个节点里面保存了节点中的数据和指向下一个节点的引用,链表的第一个节点被称为根节点(root)或头节点(head)

  技术分享图片

 二、使用Java实现基本结构

  需要一个Node类和一个Link类,Node类中存放Node中保存的数据和下一个Node的指向,Link类中保存root节点。

 1 class Node {
 2     private String data;
 3     private Node next;
 4     public Node(String data) {
 5         this.data = data;
 6     }
 7     public String getData(){
 8         return data;
 9     }
10     public void setNext(Node node) {
11         this.next = node;
12     }
13     public Node getNext() {
14         return next;
15     }
16     public void addNode(Node newNode){    //增加节点
17         if(this.next == null){
18             this.next = newNode;
19         }else{
20             //当前节点不为空,则用当前节点的下一个去继续保存
21             this.next.addNode(newNode);
22         }
23     }
24     public void printNode(){
25         System.out.println(this.data);
26         if(this.next != null)
27             this.next.printNode();
28     }
29 }
30 class List {    
31     private Node root;
32     public void add(String data){    //增加数据
33         Node newNode = new Node(data);
34         if( this.root == null){
35             this.root = newNode;
36         }else{
37             this.root.addNode(newNode);
38         }
39     }
40 }

  以上代码实现了链表的基本结构,和Link中的add()(以String对象为例子)方法,但是上面代码中Node类可以直接被外部访问,我们希望外部对链表的操作都通过Link类进行,Node类对外部隐藏,可以使用内部类来实现。

  1 class Link{
  2     private class Node{
  3         private String data;        //节点中要保存的数据
  4         private Node next;            //设置指向下一个节点
  5         public Node(String data){    //构造方法保存数据
  6             this.data = data;
  7         }
  8         public void addNode(Node newNode){        //将新节点添加到已有节点后
  9             if(this.next == null){                //判断当前节点是否为最后一个节点
 10                 this.next = newNode;            //如果是最后一个节点,则用当前节点指向新节点
 11             }else{
 12                 this.next.addNode(newNode);        //否则向后继续保存
 13             }
 14         }
 15         public boolean containsNode(String data){    //查询节点
 16             if(data.equals(this.data)){                //找到内容,返回true
 17                 return true;
 18             }else {
 19                 if (this.next != null){                //存在后续节点,继续 查找
 20                     this.next.containsNode(data);
 21                 }else{
 22                     return false;                    //不存在后续节点,没找到
 23                 }
 24             }
 25                 return false;                        
 26         }
 27         public String getNode(int index){        //根据索引查询节点
 28             //将节点编号与索引进行比较,相等则返回当前节点中的数据,不相等则找下一个编号
 29             if(Link.this.foot++ == index){        
 30                 return this.data;
 31             }else{
 32                 return this.next.getNode(index);
 33             }
 34         }
 35         public void setNode(int index , String data){        //根据索引修改Node的内容
 36             if(Link.this.foot ++ == index){                    //找到对象Node
 37                 this.data = data;            //修改data的值
 38             }else{
 39                 this.next.setNode(index, data);            //继续判断下一个节点
 40             }
 41         }
 42         public void removeNode(Node previous, String data){
 43             if(data.equals(this.data)){
 44                 previous.next = this.next;
 45             }else{
 46                 this.next.removeNode(this,data);
 47             }
 48         }
 49         public void toArrayNode(){        //将节点中数据转换成数组中的值
 50             Link.this.refArray[Link.this.foot++] = this.data;
 51             if(this.next != null){        //存在后续节点继续存放
 52                 this.next.toArrayNode();
 53             }
 54         }
 55         
 56     }
 57     //==========================上面为Node节点=================
 58     private Node root;    //定义链表中的根节点
 59     private int count = 0;    //统计节点个数
 60     private int foot = 0;    //表示Node元素编号
 61     private String[] refArray;        //对象数组,用来存放各个节点的值
 62     public void add(String data){        //链表中添加数据
 63         if(data == null){                //为了简便,暂且设置不保存null值
 64             return ;
 65         }
 66         Node newNode = new Node(data);    //实例化一个Node节点来保存数据
 67         if(this.root == null){            //判断是否存在root节点
 68             this.root = newNode;        //不存在则将当前节点设置为root节点
 69         }else{
 70             this.root.addNode(newNode);    //存在root节点则将新节点添加到链表后面
 71         }
 72         this.count ++ ;                    //保存成功count++
 73 
 74     }
 75     public int size(){        //取得节点个数
 76         return this.count;
 77     }
 78     public boolean isEmpty(){    //判断空链表
 79         //return this.count == 0;
 80         return this.root == null;
 81     }
 82     public boolean contains(String data){        //查找数据
 83         if(data == null || this.root == null){    //没有要查数据或根节点没保存数据
 84             return false ;
 85         }
 86         return this.root.containsNode(data);
 87     }
 88     public String get(int index){
 89         if(index > this.count){            //表示索引超出查询范围,没有数据
 90             return null;
 91         }
 92         this.foot = 0;                    //每次查询都是从前往后查找
 93         return this.root.getNode(index);
 94     }
 95     public void set(int index,String data){            //修改指定编号节点的内容
 96         if(index > this.count){
 97             return ;            //超出范围无法修改
 98         }
 99         this.foot = 0;                    //设置foot属性的内容
100         this.root.setNode(index,data);
101     }
102     public void remove(String data){        //移除指定数据
103         if(this.contains(data)){            //判断链表中是否存在指定数据
104             if(data.equals(this.root.data)){        //判断要删除的数据是否是root中数据
105                 this.root = this.root.next;            //移除root元素
106             }else{
107                 //继续判断下一个元素
108                 this.root.next.removeNode(this.root, data);
109             }
110         }
111         this.count--;            //删除一个节点,链表长度减一
112     }
113     public String[] toArray(){
114         if(this.root == null){
115             return null;
116         }
117         this.foot = 0;        //初始化root
118         this.refArray = new String[this.count];
119         this.root.toArrayNode();        //调用Node类中方法将每个节点数据添加到数组
120         return refArray;
121     }
122 }

  以上代码将Node类作为Link类的内部类来实现单向链表,

  public void add(String data){}:向链表中添加数据,需要为Link增加一个Node,这里将Node添加到Link的最后,每成功增加一个数据,count自增记录Link中Node的个数;

  public int size(){}:统计Link中Node元素的个数;

  public boolean isEmpty(){}:判断空链表,有两种判断方式,一种是判断root节点是否为空,另一种是判断节点个数是否为0;

  public boolean contains(String data){}:查找Link中是否存在指定数据,从root节点开始一次判断每个Node中的数据是否符合;

  public String get(int index){}:根据索引查找Link中对应的数据,索引从0开始;

  public void set(int index,String data){}:根据索引修改Link中对应的数据内容;

  public void remove(String data){}:根据指定内容移除Link中对应的Node,成功移除节点个数减1;

  public String[] toArray(){}:将Link转换成对象数组,数组长度为Link中Node的个数;

以上是关于C语言中数据结构中的单向链表的问题;的主要内容,如果未能解决你的问题,请参考以下文章

C语言提升

[ 数据结构--C语言 ] 无头单向非循环链表的简单实现(单链表)

C语言一篇文章带你彻底了解单向链表的增删查改

C语言反转单向链表的代码

C语言-链表(单向链表双向链表)

C语言-链表(单向链表双向链表)