本文共 2734 字,大约阅读时间需要 9 分钟。
今天写一下自己学习链表的总结吧~
首先要先说一个符号 -> 由于许久没有写C了,所以陡然看到确实心虚的不行,有赶快把书温习了一下,原来他是:结构体指针,是作用于指向结构体的,具体的大家可以看一下别的帖子来了解一下。 接下来要说一下链表的特点了: 在顺序表中,所有的元素紧密相挨,所以他们的地址我们其实可以推算出来,但是到了链表中,他们会就像是一条线性关系,就是我只知道我的下级是谁,于是呢,当我们查找起来就只能每次都要从头遍历一遍了。 而也是正因为如此,每个链表结点都分为了数据域和指针域。 数据域,顾名思义,用来存储数据的,而指针域则是建立联系关系的,用来指向下一个【单链表】或者上下【双链表】。 那么话不多说,我们以单链表为例,用一段完整的代码来给大家展示一下链表的实现吧:#include#include /*创建一个链表格式*/typedef struct Link{ int elem; //代表数据域,用来存储数据 struct Link *next; //代表指针域,用来指向下一个元素 }link;/*接下来来创建一个链表(1,2,3,4,5)*/link *initLink(){ link *p = (link *)malloc(sizeof(link));//创建一个头结点 link * temp = p;//声明一个指针指向头结点,我们以后基本上都是通过它来找到这个链表 /*生成链表*/ int i; for( i = 1; i < 6; i++){ link *a = (link *)malloc(sizeof(link)); a->elem = i; a->next = NULL; temp->next = a; temp=temp->next; } return p;} /*查找某结点*/ /*由于在链表中,我们只能知道头指针,所以当我们想要去寻找后面元素的时候,我们只能进行遍历来寻找*/ int selectElem(link *p, int elem){ link *t = p; int i = 1; while ( t -> next){ t = t->next; if(t -> elem == elem){ //当我们传入的p中的elem值与elem值相等时 return i; } i++; } return -1; } /*更改值域的值*/ /*首先通过遍历来找到该结点,直接更改值即可*/ link *amendElem(link *p, int add, int newElem){ //add 为我们需要更改的位置,newElem是需要更改的值 link *temp = p; temp = temp->next; //遍历之前,首先找到头结点 int i; for(i = 1; i < add; i++){ //找到需要更改的位置 temp = temp->next; } temp->elem = newElem; return p; } /*插入结点*/ /*我们插入节点只需要将需要插入的结点next指针指向插入后的结点,将插入位置之前的结点的next指向该插入结点*/ link *insertElem(link *p, int elem, int add){ link *temp = p;//创立临时结点temp int i; for(i = 1; i < add; i++){ //找到所需要插入的位置的前一个结点 if(temp == NULL) //如果发现插入的地方在整个链表最后的位置之后 { printf("插入位置无效"); return p; } temp = temp->next; } //船舰我们需要插入的结点c link *c = (link *)malloc(sizeof(link)); c->elem = elem; c->next = temp->next; temp->next = c; return p; } /*显示我们的链表*/ void display(link *p){ link *temp = p; while(temp->next){ temp = temp->next; printf("%d", temp->elem); } printf("\n"); } /*从链表中删除结点*/ /*需要注意的是,我们将结点拿出后,需要手动释放,回收内存空间*/ link *delElem(link *p, int add){ link *temp = p; int i; for(i = 1; i < add; i++){ temp = temp->next; } link *del = temp->next; //设置一个指针指向需要被删除的结点,防止丢失 temp->next = temp->next->next; //将前一个结点指向需要删除的结点后的结点 【忽略该结点】 free(del); //手动释放该结点 return p; } int main(){ //初始化链表 printf("初始化链表为:"); link *p = initLink(); display(p); printf("在5的位置插入元素9:"); p = insertElem(p, 9, 5); display(p); printf("删除元素3:"); p = delElem(p, 3); display(p); printf("查找元素4的位置:"); int address= selectElem(p, 4); if(address == -1){ printf("没有该元素"); }else{ printf("元素4的位置为:%d\n", address); } printf("更改1的位置的数据为7:"); p = amendElem(p, 1, 7); display(p); }
在链表中,我们存储密度一说,一般是数据域所占的单个结点的比例,一般当然比例越大存储密度越大啦,而顺序表由于没有指针域所以一般顺序表的存储密度都是1~
转载地址:http://huyg.baihongyu.com/