链表

来源:互联网 发布:angularjs.js 2.0下载 编辑:程序博客网 时间:2024/06/16 03:15

典型数据结构:数组、链表、队列、栈、二叉树、Hash表、图

一、链表

1、头指针和头结点

头指针

a) 头指针是指向链表第一个结点的指针,如果存在头结点,头指针就是指向头结点的指针。

b) 头指针具有标识作用,常用头指针冠以链表的名字

c) 无论链表是否为空,头指针均不为空(对此句话不认同)。头指针是链表的必要元素。

 

头结点

a) 头结点是为了操作的统一和方便而设立的,位于第一个数据节点之前,其数据域一般无意义(也可以存放链表的长度)。

b) 有了头结点,在第一元素前插入节点和删除第一节点,其操作与其他节点的操作就统一了。

c) 头结点不是链表的必要元素。


头指针只是一个指针,没有实例化;头结点是一个实例化的节点。


2、链表的程序实现

1)注意:在main函数里面定义的linklist list; 这个地方定义的是头指针,头结点在creat()函数里面创建,头结点是占有实际空间的,需要动态分配内存。

creat1(&list,3); //由于creat1()函数需要创建头结点,而头指针(即list)需要指向头结点,list原来是空,在函数里要改变,要想保留结果必须将其指针传入函数内部。注意c语言不能引用,但是可以传递指针,此处是提取指针,不要混淆掉。插入和删除虽然会改变链表,但是不会改变头指针,所以不用定义为linklist的指针(虽然书上这样写)。

2)双链表和单链表的操作大部分相同,因为只要朝一个方向遍历就可以。构造、插入和删除函数,有区别。一般涉及3个节点,4条连接。

注意,双链表初始的时候,只有头结点,头结点的prior指针和next指针均指向自身

#include<iostream>using namespace std;/*注意这里linklist是节点的指针类型,一般用于定义头指针,由于头指针具有标识作用,所以可以认为其是用来定义链表的。*/typedef struct node{int data;node *next;}node,*linklist;/*获取第i个元素值。注意,尽量用指针,因为C不支持引用*/bool getelem(linklist l,int i,int *elem){node *p = l->next;/*确定边界最好的办法就是假设一种情形,边界设置好的话,操作的形式会统一地很好。*/while ((i > 1)&&(p!=NULL)) {p = p->next;i--;}if (p == NULL) return false;  *elem = p->data;return true;}/*在第i个元素前,插入元素。*/bool linsert(linklist l, int i, int elem){node* p = l;while ((i > 1) && (p != NULL)){p = p->next;i--;}if (p == NULL) return false;/*C++和C动态分配存储的方式不同,malloc返回的指针是void的,必须强制转换。C++为struct提供默认的构造函数*/node *temp = (node*)malloc(sizeof(node));//node *temp=new node();temp->next = p->next;temp->data = elem;p->next = temp;return true;}/*删除第i个元素,并将值赋给elem,删除的时候,要先保留删除位置,否则会丢失*/bool ldelete(linklist l,int i,int *elem){node* p = l;while ((i>1)&&(p->next!=NULL)){p = p->next;i--;}node *q = p->next; if (q == NULL) return false;*elem = q->data;p->next = q->next;free(q);return true;}bool creat1(linklist *l, int n)  //头插{*l = (node *)malloc(sizeof(node));(*l)->next = NULL;  //指针一定要初始化while (n > 0){node *temp = (node *)malloc(sizeof(node));temp->next = (*l)->next;temp->data = n;(*l)->next = temp;n--;}return true;}bool creat2(linklist *l, int n)  //尾插{node *tail;(*l) = (node *)malloc(sizeof(node));(*l)->next = NULL;tail = *l;while (n > 0){node *temp = (node *)malloc(sizeof(node));temp->next = NULL;temp->data = n;tail->next = temp;tail = temp;n--;}return true;}void lprint(linklist l){node *p = l->next;while (p != NULL){cout << p->data<<" ";p = p->next;}cout << endl;}int main(){linklist list;  //这个地方定义的是头指针,头结点在creat函数里面创建,头结点是占有实际空间的,需要动态分配内存linklist list2;int a;list = NULL;cout << "原始:" << endl;creat1(&list,3); //由于,creat函数需要创建头结点,而头指针(即list)需要指向头结点,                         //list原来是空,在函数里要改变,要想保留结果必须将其指针传入函数内                         //部。注意c语言不能引用,但是可以传递指针,此处是提取指针,不要混淆掉。lprint(list);cout << "删除后:" << endl;ldelete(list,1,&a);lprint(list);cout << "插入后:" << endl;linsert(list,2,7);lprint(list);cout << "尾部插入方式:" << endl;creat2(&list2, 3);lprint(list2);system("pause");return 0;}

#include<iostream>using namespace std;typedef struct node{int data;node *prior;node *next;}node, *linklist;/*第i个节点前插入元素elem*/bool linsert(linklist l, int i, int elem){node *q;node *p = l->next;;while ((i > 1) && (p != NULL)){p = p->next;i--;}if (p == NULL) return false;node *temp = (node*)malloc(sizeof(node));temp->data = elem;/*插入操作涉及3个节点*/q = p->prior;//q是第一个节点,temp是第二个节点,p是第三个节点q->next = temp;temp->prior = q;temp->next = p;p->prior = temp;return true;}bool ldelete(linklist l,int i,int *elem){node *p = l->next;while ((i > 1) && (p != NULL)){p = p->next;i--;}if (p == NULL) return false;node *q,*r;*elem = p->data;q = p->prior;r = p->next;q->next = r;r->prior = q;return true;}void creat(linklist *list,int n){(*list) = (node*)malloc(sizeof(node));(*list)->next = (*list);(*list)->prior = (*list);node *p = (*list);node *r;while (n > 0){/*类似插入,也是有3个节点*/node *temp = (node*)malloc(sizeof(node));temp->data = n;r = p->next;p->next = temp;temp->prior = p;temp->next = r;r->prior = temp;n--;}}void lprint(linklist l){node *p;p = l->next;while (p != l){cout << p->data << " ";p = p->next;}cout << endl;}int main(){int a;linklist list=NULL;creat(&list, 3);lprint(list);linsert(list,2,7);lprint(list);ldelete(list,3,&a);lprint(list);system("pause");return 0;}
原创粉丝点击