你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

链表基本操作的实现

[复制链接]
巅峰残狼 发布时间:2014-12-2 17:33
本程序转自网络,特别感谢网友白光( i6 g7 @7 P) u+ i" _- J3 J4 ~/ @2 z' o$ N

' o; o: _' L3 x* F- P1 F4 ?: P1 q#include <stdio.h>
, u, t! N$ H% j; q* ~" r4 ~2 v#include <malloc.h>& z* ~( `7 v5 P* z& W
#define LEN sizeof(struct student)! T( Q) u9 }5 q* H
% a" w9 b9 r0 U8 U& I
/*----------------数据定义----------------------*/ 4 Z2 |+ l* x6 l& x" X: p
6 v  U% ~% F7 X
//定义一个学生信息的结构体,包括学号,姓名和结构体类型的指针
, E! |' g; p: D5 a0 Ystruct student
" M# p+ k2 r8 q) H! x# g0 ^. g{
6 Y! l0 g3 H: V    long num;                //学号
) |% W2 p0 `* o    char name[128];            //姓名
5 W- Z- ]4 `' J. Z, Z$ ^" L* |    struct student *next;    //结构体指针
' c  y% }$ O$ |};# X: Q+ |$ d( x0 o" h

8 r+ G+ l; Y1 q- ptypedef struct student * stuNode;$ u  I. G0 I. H8 _7 j# D
- [+ i: n, u* [# K* J5 s0 o
int n=0;                    //全局变量,记录链表的长度
9 x# H- f* O9 g/ L2 v* u
; a% k% ^% C4 {# q3 f) c* P/*---------------函数声明---------------------*/3 f$ l% J- Z. W4 B
7 z& {0 t3 }5 ]2 `! J6 G# P7 `
stuNode Create();            //创建一个新的链表                     
% o5 I9 Y1 ~0 y7 L6 e+ n2 R+ L9 z2 C4 J2 d
void Print(stuNode head);    //通过传入的链表头指针打印整个链表
  ^; T: G8 b# m0 C
* k9 N- Z! {4 i+ K6 l# FstuNode Delete(stuNode head,int num);    //通过传入的链表头指针和学生学号删除节点 : O: }1 ^+ X3 U, T" x  F2 ?

' D, _/ `4 W7 S% H/ X0 j* LstuNode Insert(stuNode head,stuNode newStu);    //依照学生学号的顺序向链表中插入新元素
/ c3 o7 Y5 G4 [2 P8 _& I# K$ O2 {% p
. t7 l0 H! ^) p: y8 l5 e
/*---------------函数定义----------------------*/
* z  H+ \/ u1 W3 A4 R7 n. p- ^7 {6 T+ V% I. u7 V0 ^: a
struct student *Create()
* a3 t( d5 |6 N5 u5 l{, n0 u5 a) `$ h  `& ]' R* X, A
    struct student *head,*p1,*p2;
/ p% W2 B" n6 X" e4 `* V1 R  X8 Z" W" Q3 z
    //开辟一个LEN大小的空间,并让p1,p2指针指向它 / L: }' v7 E8 w9 h5 u2 w2 u$ \
    p2=p1=(struct student *)malloc(LEN);
; ~1 ^. T% [- {2 D0 d; o* B    //将头指针置为NULL : ]4 M% o6 I; b" l/ w
    head=NULL;
1 s0 j, x* j+ v# x# J2 g& M5 D2 {
2 r7 h6 L+ L" p& ^; d2 I' P2 x/ n    //创建链表节点并给节点的元素赋值
7 u% X; H( [* E, R    printf("请输入学生的学号和姓名:");; b" \0 N/ [+ w$ g
    scanf("%ld %s",&p1->num,p1->name);
( d8 Y' ?$ A1 m8 y: b! ]! e    while(p1->num!=0)/ S$ O& g) e+ v4 m4 [* M# B1 Z
    {8 ~$ w% J$ b4 t) M
        n=n+1;( ]. n1 Q$ d7 g- _8 d$ K: ?
        if(NULL==head)
/ _. B8 P; o  V5 t" W        {
5 ]8 |5 v. q8 Z0 P& Q4 r            head=p1;
1 P" U( A% c2 x( Y        }
0 O" z( o3 K/ F        else
) T- |& d. l; K. G* ?        {: j9 z0 t- ~! O1 F$ m' a
            p2->next=p1;4 M0 r: B! J  L: }2 b4 b( D
        }/ a' E  z! @3 w# G* ?' G
        p2=p1;1 q1 K' z6 ^  _' Q5 u8 y  i/ ?4 w3 [
        p1=(struct student *)malloc(LEN);9 E3 _0 S5 c" b4 H
        printf("请输入学生的学号和姓名:");
* ~" L- x4 [  y3 @        scanf("%ld %s",&p1->num,p1->name);* h9 k" ]: R% n3 ^
    }
0 @3 {7 V& Z: M. M$ y7 Q' l* f    //将尾节点的指针置为NULL
9 q! t3 X7 @9 q! t( p    p2->next=NULL;/ x; _& t7 `/ r7 e5 l
    return head;
0 O% N3 ]& X; C$ r}* ]" F1 _% U$ j- }

+ P# t! d  s- f  j0 B
5 m, N3 {$ R  H  x: b4 hvoid Print(struct student *head)
! n5 \: T7 |4 h5 c6 J5 g! Z{
1 O5 Z" L5 C5 Y+ s    struct student * p;
8 F- d' ?. q8 z+ M6 }7 E  W    p=head;
7 S  D; G" e, ^5 E/ E% j2 Q4 n8 N  J0 s5 u1 a4 K4 ^* p
    //判断链表是否为空
% q" N0 ?+ k, x* R2 I    if(NULL==head)& b, ?4 K& b8 U% p3 F0 A
    {& j' D" t# ^& u7 @2 f- v& u
        printf("链表为空!\n");
0 P5 k1 r' b! z7 i$ W0 h3 B! Y        return head;, c2 p' ~  \! \3 _$ p$ _/ x5 R
    }
$ v; W/ ~+ t2 O- z5 S    else
7 o; R! H/ b+ R    {
+ I' c* J4 z& L0 E+ X        //循环打印链表中的元素
) C2 h4 D' i6 W! J& W: B$ {7 X, {        printf("%d 个记录分别为:\n",n);
# c6 J1 q$ h) i5 i        while(p!=NULL)
$ {: `0 j5 y( }* M0 o        {
' k7 ]  c; `  S# f3 w( k            printf("%ld %s\n",p->num,p->name);
8 \# G: t: g/ D- m# k& {7 B) c            //指针指向下一个节点 " F0 ^0 @: V( Q. o% e3 j/ T
            p=p->next;' B6 E+ A, g0 V& K3 s! P6 ^
        }) N, f, x6 p# O: p
    }8 s, D4 _3 {8 F) g! N5 B: ~
}
; Z& K' ^" s' x% Z( k3 H2 i/ h8 x3 [7 _( f& T- c9 d
, B  Q! Z4 s& p  J/ \' _
struct student *Delete(struct student * head,int num)* o1 Y5 b0 O6 N# E, \1 f
{2 e" v+ o6 {# p6 b3 X* p
    struct student *p1;
$ {" w8 p3 S2 r" m7 X    struct student *p2;
- E2 L1 R/ r, k    p1=head;" ^6 b/ X) K; p. |* `5 i9 d' m$ e
    //判断链表是否为空
- A' n# b  s  H( Q' R  y" ]$ p    if(NULL==head)
5 k2 }2 b5 ], o9 v/ Q* B    {
6 r/ P- _0 I8 s0 T  V8 @        printf("链表为空!\n");
3 t3 B+ ]7 D0 g. _        return head;
# q' ~- c! n  s    }
4 x$ `% k  b  `# j) y    //遍历节点,判断当前节点是不是需要删除的节点及是否为尾节点5 k: p; ~7 \. m. U/ p% ]" o% x, ~
    //如果找到相应节点,或者已经遍历到尾节点就跳出循环 ! T$ d! u/ ^+ s( @, @8 @- G
    while(p1->num!=num&&p1->next!=NULL)0 ~. A& V2 A1 L' e
    {9 N8 t' `: B, ]5 k
        p2=p1;3 q$ D7 L1 c. L4 u2 Q& j
        p1=p1->next;$ q1 ?4 z- S. J8 z6 R
    }
1 L$ g; s/ L+ M& h4 R1 q1 s! M    //判断是否找到相应节点
6 G& w3 V- [5 G* @    if(p1->num==num)& j9 R- _7 v! o0 b  a
    {
: ~3 r/ X6 b8 V" p/ @        //要删除的节点是不是链表的第一个节点* |0 I) @1 H7 J$ H
        //如果是,就将头指针指向该节点的后一个节点& e0 y# x. x$ {# ]% Y2 l; b5 g
        //如果不是,就将该节点的前一个节点的指针指向该节点的后一个节点
: A3 W5 Y4 l7 }/ e9 H  K) L        if(head==p1)
9 i# a3 s) c; x2 J7 W. i        {
8 M9 F6 y' D3 Y' w& L            head=p1->next;
7 x! b0 a4 n+ N        }
" K9 A7 J- F9 X$ `2 Y+ b6 t        else# q3 m; D* E) \/ h# e( _
        {
( z3 }8 v' ~  k+ q  y            p2->next=p1->next;* W- T9 l2 h% Z+ H
        }
& d! N. u3 h0 B) A        n=n-1;, y; k! Q$ Y  k' g" F2 R
        printf("%ld 节点已删除.\n",num);
9 j2 h1 ~) i: ]+ T    }: [1 [, T, \& @& ]$ U- E
    else
' ]( M& Y) H/ P. P: r( [: i    {6 s. s1 H9 M% b/ W, K: N
        printf("链表中没有要删除的元素.\n");" b" n. X, k0 o9 k
    }# a7 |) _% [1 h1 |
    return head;! {. t) `' x, t
}
! s( f0 n9 @+ F/ F2 b
* E5 ~3 d3 d6 m7 R' `  O0 k7 o: e9 u1 v
struct student *Insert(struct student * head,struct student * newStu). F/ W$ s" U+ `# Q* \( v
{
3 s' _$ c# X% p" Q    struct student *p0;
0 k# b! u! x$ t& j/ t. Q+ T    struct student *p1;
$ ]: J3 o7 S4 w' l    struct student *p2;
5 B6 w- ^3 G4 p# Q# C' q/ M( E8 l    p0=newStu;' i( n! a4 \/ b$ t
    p1=head;, n! r* X  |$ q: T; I$ d
    //判断链表是否为空,如果是空链表,就将新节点作为第一个节点
- a* c4 x! T% j$ h: Z5 y  V9 Y    if(NULL==head)
* q4 i) a# |! P# ]4 n) K    {; W- I! B2 `  H* m) c$ M7 i
        head=p0;+ Q% O3 [9 B/ K$ E( U
        p0->next=NULL;
  H$ g' Y& V1 {/ t2 G6 [$ R    }6 h& ~' E# w; _9 i! F
    else
6 N! r) ~6 P$ Q; k! P$ w" M    {
0 E( U9 c2 H7 I+ _. J* e        //遍历每一个节点中的学号,与新学号比较大小5 Y0 s+ T  l# p$ v
        //如果找到一个学号比新学号大,就将新学号的节点插入它之前
' g9 u; o  B& a4 c* R+ ]        //如果尾节点的学号仍比新学号小,就将新节点插入到链表尾部 3 |1 u# h: l# F. N3 |- g$ ?/ V( l; L
        while((p0->num > p1->num)&&(p1->next!=NULL))
' {1 `0 W* a/ D, F: k+ Y0 q& U7 e        {0 M  @) i5 u) R% {: s
            p2=p1;
: S! X$ E9 V; x2 u. T: u) B2 R  K            p1=p1->next;
" U- W8 L' ?3 B$ C7 D        }
* u- j5 h- i  Y& ~# @6 q        //找到一个比新学号大的节点
# H1 G& T* ]  w3 c        if(p0->num <= p1->num)5 u. V+ E; G7 r
        {9 k8 J# E6 A5 `# H. l
            //判断该节点是否为头节点,如果是,则将新节点设置为头节点
& ]( K: Z: f( Y5 M# n" J. r( r            if(p1==head)+ W; c% z6 G1 [: k7 K* J; a% x7 p
            {( U4 d$ I0 Y- `, b3 U
                head=p0;9 z" ~: r! ~8 A
            }5 V: n. q% b" p- v, @! z% ^
            else8 }% _8 m) r) [# u2 z
            {
" |5 G6 D' p9 ~1 P4 M6 g                p2->next=p0;+ a. k) ~- ~+ V' ]/ K+ V; s
            }3 U1 O9 J  q6 U( @
              p0->next=p1;4 ]' I- y; ?5 _# S: `1 h1 V
        }$ b, q: T* K! @% P9 ]1 m3 A# a
        else
6 {! m3 Z2 h; e        {
# ]' @& A- f! Z            p1->next=p0;6 f- I6 u- F1 E# P- K
            p0->next=NULL;
0 T1 x9 U% ]5 D2 L  q        }: q  B3 {/ h% ^: x% t5 t
    }
! S* v* ], d1 {) ^( H0 n" {, H8 M    //链表长度加1
. D8 |* Y5 S3 \2 a' {4 ~    n=n+1;
) R! n( t1 W/ G% |2 |) G    printf("%ld 插入成功!\n",newStu->num);$ C- s8 G  A3 ~- y, G6 b$ ^# a3 M# b
    return head;
( `8 b; c9 G2 S7 W! W) p}
: Q% }6 c7 z" b# j# I8 B9 V9 N: G2 a3 L' `6 X
void main(): _" d) R" j. U: r; ~1 I+ y
{
$ B! O( d' u5 K% Q    struct student *head;4 @( I4 }4 a6 }0 d- j1 P2 I
    struct student *stu;
+ H( W1 |. M0 L0 q8 `    int num;
0 t5 t6 u$ s3 r+ P9 D. k; [0 r8 a6 g    head=Create();7 F" H- A0 D3 C! {1 u' c" g
    Print(head);" V5 k6 G1 a7 L% l' D' R: \# e
    printf("请输入要删除的学号:");
; N2 A  f- s8 v! ~% g    scanf("%ld",&num);
- S( J! ?. B# l+ C2 [- I9 {4 S7 s8 a    while(num!=0)
1 X& W+ B4 N7 ~" b* e    {
/ W- h# F  R2 p        head=Delete(head,num);* S* v1 f( O& E% [' N
        Print(head);: P. U; O5 @  V% O* I& @
        printf("请输入要删除的学号:");7 l% s9 p+ I: j
        scanf("%ld",&num);
: {7 O) n5 q, _, F  M$ N    }: C3 {$ v% y/ O- e) }3 i* g
    printf("请输入要插入的节点:");/ v4 z4 C. e4 c
    stu=(struct student *)malloc(LEN);
* b1 W" z7 [) L* v    scanf("%ld %s",&stu->num,stu->name);/ p7 |$ Y$ |' U7 W0 ^- _
    while(stu->num!=0)
. @' ]; x# _0 O6 N) W1 I* C+ E    {
4 K, C2 u' ?) O        head=Insert(head,stu);$ f8 {/ _# |( e. L" e
        printf("请输入要插入的节点:");0 s0 j, \$ K1 b# S# b3 k
        stu=(struct student *)malloc(LEN);
( v* {" P7 C- K' `. u  I        scanf("%ld %s",&stu->num,stu->name);, I8 |$ b6 b6 j* r' |8 O5 r6 w
    }
0 P5 L/ q* o! d9 w    Print(head);
) B$ c+ y; x& S+ D; |}
9 ]  O, A2 _- i9 C6 H
+ [4 j9 `3 R6 |, h
收藏 1 评论4 发布时间:2014-12-2 17:33

举报

4个回答
霹雳之火 回答时间:2014-12-3 22:26:28
链表太常用了,顶起
沐紫 回答时间:2014-12-4 13:19:26
支持版主大大!
木易-357428 回答时间:2015-1-9 15:17:37
支持一下版主
花落成尘眼泪 回答时间:2018-11-30 13:09:22
正在学链表,帖子真心不错,要是楼主能够分享整个工程模板,那就对我们部分小白太好了

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版