c语言链表大例题
数据结构经典题目及c语言代码
数据结构经典题目及c语言代码一、线性表1. 顺序表顺序表是一种利用连续存储空间存储元素的线性表。
以下是一个顺序表的经典题目及C语言代码实现:```c#define MaxSize 50typedef struct {int data[MaxSize]; // 存储元素的数组int length; // 顺序表的当前长度} SeqList;// 初始化顺序表void initList(SeqList *L) {L->length = 0;}// 插入元素到指定位置void insert(SeqList *L, int pos, int elem) {if (pos < 1 || pos > L->length + 1) {printf("插入位置无效\n");return;}if (L->length == MaxSize) {printf("顺序表已满,无法插入\n"); return;}for (int i = L->length; i >= pos; i--) { L->data[i] = L->data[i - 1];}L->data[pos - 1] = elem;L->length++;}// 删除指定位置的元素void delete(SeqList *L, int pos) {if (pos < 1 || pos > L->length) {printf("删除位置无效\n");return;}for (int i = pos - 1; i < L->length - 1; i++) {L->data[i] = L->data[i + 1];}L->length--;}// 获取指定位置的元素值int getElement(SeqList *L, int pos) {if (pos < 1 || pos > L->length) {printf("位置无效\n");return -1;}return L->data[pos - 1];}```2. 链表链表是一种利用非连续存储空间存储元素的线性表。
C程序设计(链表)习题与答案
一、单选题1、链表不具有的特点是()。
A.不必事先估计存储空间B.插入、删除不需要移动元素C.可随机访问任一元素D.所需空间与线性表长度成正比正确答案:C2、链接存储的存储结构所占存储空间()。
A.分两部分,一部分存放结点值,另一部分存放结点所占单元数B.只有一部分,存放结点值C.分两部分,一部分存放结点值,另一部分存放表示结点间关系的指针D.只有一部分,存储表示结点间关系的指针正确答案:C3、链表是一种采用()存储结构存储的线性表。
A.网状B.星式C.链式D.顺序正确答案:C4、有以下结构体说明和变量的定义,且指针p指向变量a,指针q指向变量b,则不能把结点b连接到结点a之后的语句是()。
struct node {char data;struct node *next;} a,b,*p=&a,*q=&b;A.(*p).next=q;B.p.next=&b;C.a.next=q;D.p->next=&b;正确答案:B5、下面程序执行后的输出结果是()。
#include <stdio.h>#include <stdlib.h>struct NODE {int num; struct NODE *next;};int main(){ struct NODE *p,*q,*r;p=(struct NODE*)malloc(sizeof(struct NODE));q=(struct NODE*)malloc(sizeof(struct NODE));r=(struct NODE*)malloc(sizeof(struct NODE));p->num=10; q->num=20; r->num=30;p->next=q;q->next=r;printf("%d",p->num+q->next->num);return 0;}A.30B.40C.10D.20正确答案:B6、下面程序执行后的输出结果是()。
c语言 链表笔试题
关于链表常考的笔试面试题1、单链表逆序,在原列表的基础上进行调整struct ListNode* ReverseList(struct ListNode* pHead ){// write code here//判断第一个元素是否为空,如果为空,则返回NULL;并判断第二个元素是否为空,如果为空,则不需要逆序,直接返回if(pHead == NULL || pHead->next == NULL) return pHead;//定义三个节点指针,分别存放前一个操作节点,当前操作节点,下一个操作节点struct ListNode *temp1 = NULL,*temp2 = pHead,*temp3 = pHead->next;//当下一个操作节点存在时,执行循环,将当前节点的next指向前一个节点,并移动三个指针位置while(NULL != temp3){temp2->next = temp1;temp1 = temp2;temp2 = temp3;temp3 = temp2->next;}//当temp3为空时,说明temp2指向最后一个节点,只需将它的next指向前一个节点temp2->next = temp1;return temp2;}2、找出链表的倒数第n个节点int query_reverse(List* list,size_t index){Node* f = list->head;Node* s = list->head;for(int i=0;i<index;i++){f = f->next;if(f == NULL) return false;}while(f){f = f->next;s = s->next;}return s->data;3、判断链表中是否有环bool is_ring(List* list){Node* fast = list->head;//快指针Node* slow = list->head;//慢指针while(fast && fast->next){fast = fast->next->next;//快指针每次走两步slow = slow->next;//慢指针每次走一步if(slow == fast) return true;//如果相同,则该链表有环}return false;}4、找到环形链表的入口int ring_in(List* list){if(is_ring){Node* fast = list->head;Node* slow = list->head;Node* meet = list->head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;meet = meet->next;if(slow == fast){slow = list->head;fast = meet;fast = fast->next;slow = slow->next;if(slow == fast)return fast->data;}}}return -1;}5、合并两个有序链表,合并后依然有序List* merge_list(List* list1,List* list2){Node* m = list1->head->next;Node* n = list2->head->next;Node* new = create_node();if(list1 == NULL) return list2;if(list2 == NULL) return list1;if(list1== NULL && list2== NULL) return NULL;while(list1&&list2){if(m->data < n->data){new->next = m;m = m->next;}else{new->next = n;n = n->next;}new = new->next;}new->next = m?m:n;return new;}6、判断两个链表是否是Y型链表bool is_y(List* l1,List* l2){int cnt1 = 0,cnt2 = 0;Node* m = l1->head->next;Node* n = l2->head->next;while(m){cnt1++;m = m->next;}while(n){cnt2++;n = n->next;}if(cnt1>cnt2){for(int i=0;i<cnt1-cnt2;i++){m = m->next;}}else{for(int i=0;i<cnt2-cnt1;i++){n = n->next;}}while(m == NULL || n = NULL){m = m->next;n = n->next;if(m = n) return true;}return false;}。
链表的经典习题
链表的经典习题练习1•:链式栈//链式栈(top指向第⼀位⽆效的头结点)public class LinkedStack<E> {Node<E> top;//内部类class Node<E> {protected E data;protected Node<E> next;public Node(E data) {this.data = data;}}public LinkedStack() {top = new Node(new Object());}//头插法public void push(E val){Node<E> newNode=new Node(val) ;//创建⼀个值为val的节点newNode.next=top.next; //新插⼊节点的next指向原top指向的nexttop.next=newNode;//再把top.next指向新节点}//获取栈顶元素并删除public E remove(){if(top.next==null){throw new UnsupportedOperationException("the stack has been empty");}E result=top.next.data;top.next=top.next.next;return result;}public E peek(){if(top.next==null){throw new UnsupportedOperationException("the stack has been empty");}return top.next.data;}//从top节点的下⼀个开始遍历,不为空则⼀直的打印public void show(){Node<E> tmp=top.next;while (tmp!=null){System.out.print(tmp.data+" ");tmp=tmp.next;}System.out.println();}public static void main(String[] args) {LinkedStack<Integer> l=new LinkedStack();l.push(3);l.push(4);l.push(5);l.show();System.out.println(l.peek());l.remove();//删除5l.show();l.remove();//删除4l.show();l.remove();//删除3l.show();}}练习2:查找链表中倒数第k个节点//单链表查找倒数第k个节点class FindLastK<E> {Node<E> head;class Node<E> {protected E data;protected Node<E> next;public Node(E data,Node<E> next) {this.data = data;this.next=next;}}////构造函数,第⼀个头结点有效,所以不需要构造函数// public FindLastK() {// this.head = new Node(new Object(),null);// }//找倒数第k个数的⽅法public E lastK(int k){Node<E> cur1=this.head.next;Node<E> cur2=this.head;//cur2指向头if(head==null){return null;}if(k>getLenth()||k<=0){return null;}else if(k==getLenth()){return head.data;}for(int i=1;i<=k;i++) {cur2=cur2.next;if(cur2==null){return null;}}while (cur2.next!=null){cur2=cur2.next;cur1=cur1.next;}return cur1.data;}//获取链表长度public int getLenth(){int length=0;Node<E> cu=head;if(head==null){return 0;}while (cu!=null){ //应该让cur去遍历,不能让head直接遍历,否则打印⼀次后show再次打印链表就会空 length++;cu=cu.next;}return length;}//尾插法public void add(E val) {Node<E> newNode = new Node(val,null);Node<E> current = head;if(head==null){head=newNode;return;}while (current.next != null) {current = current.next;}current.next = newNode;// newNode.next=null;}public void show() {Node<E> current = head;if(current==null){System.out.println("链表空!!");return;}while (current!=null&¤t.next!= null) {System.out.print(current.data + " ");current = current.next;}System.out.println(current.data);}}public class FindLastKTest{public static void main(String[] args) {FindLastK<Integer> f=new FindLastK<>();f.add(3);f.add(4);f.add(5);f.add(6);f.show();System.out.println("该链表的长度:"+f.getLenth());System.out.println(stK(1));//6System.out.println(stK(4));//3System.out.println(stK(5));//nullf.show();}}练习3:找到带环链表的⼊⼝节点import sun.awt.image.ImageWatched;//单链表查找倒数第k个节点public class LinkedExercise<E> {Node<E> head;static class Node<E> {protected E data;public Node<E> next;public Node(E data, Node<E> next) {this.data = data;this.next = next;}}////构造函数,第⼀个头结点有效,所以不需要构造函数// public FindLastK() {// this.head = new Node(new Object(),null);// }//找倒数第k个数的⽅法public E lastK(int k) {Node<E> cur1 = this.head.next;Node<E> cur2 = this.head;//cur2指向头if (head == null) {return null;} else if (k > getLenth() || k <= 0) {return null;}//如果找的倒数第k个恰好为链表长度,直接将头结点的数返回else if (k == getLenth()) {return head.data;}for (int i = 1; i <= k; i++) {cur2 = cur2.next;if (cur2 == null) {return null;}}//两个节点同时遍历,快节点遍历到最后⼀个节点时,慢节点指向的节点就是要找的节点while (cur2.next != null) {cur2 = cur2.next;cur1 = cur1.next;}return cur1.data;}//获取链表长度public int getLenth() {int length = 0;Node<E> cu = head;if (head == null) {return 0;}while (cu != null) { //应该让cur去遍历,不能让head直接遍历,否则打印⼀次后show再次打印链表就会空 length++;cu = cu.next;}return length;}//判断单链表是否有环/*** 快慢指针,先通过两个指针找到环内的节点,然后再⼀个节点从相交节点出发,* 另⼀个节点从头结点出发,再次相交的节点就是环的⼊⼝节点** @return*/public E getLinkCirclrVal() {Node<E> slow = this.head;Node<E> fast = this.head;//找到了相交节点while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;if (slow == fast) {break;}}if (fast == null) {return null;} else {fast = this.head;while (fast != slow) {fast = fast.next;slow = slow.next;}return slow.data;}}//尾插法public void add(E val) {Node<E> newNode = new Node(val, null);Node<E> current = head;if (head == null) {head = newNode;return;}while (current.next != null) {current = current.next;}current.next = newNode;// newNode.next=null;}public void show() {Node<E> current = head;if (current == null) {System.out.println("链表空!!");return;}while (current != null && current.next != null) {System.out.print(current.data + " ");current = current.next;}System.out.println(current.data);}//构造带环的链表public void con(LinkedExercise<E> link){//将两个节点都指向头LinkedExercise.Node list=link.head;LinkedExercise.Node p=link.head;//list遍历到最后⼀个节点while (list.next!=null){list=list.next;}//让最后⼀个节点的写⼀个指向头结点的下⼀个 6指向5list.next=p.next.next;}public static void main(String[] args) {LinkedExercise<Integer> f = new LinkedExercise<>();f.add(3);f.add(4);f.add(5);f.add(6);f.show();System.out.println("该链表的长度:" + f.getLenth());System.out.println(stK(1));//6System.out.println(stK(4));//3System.out.println(stK(5));//nullf.con(f);System.out.println("环的⼊⼝节点:"+f.getLinkCirclrVal());}}练习4:合并两个有序的链表(头结点⽆效时)包含头结点⽆效的⼤多数函数:class SingleLinekdListTakeHead<E extends Comparable> {protected Node<E> head;//头节点class Node<E> {protected E data;//数据域protected Node<E> next;//next引⽤域public Node(E data, Node<E> next) {this.data = data;this.next = next;}}//初始化headpublic SingleLinekdListTakeHead() {head = new Node(new Object(), null);}//在head之后直接插⼊⼀个节点,头插法public void addHead(E element) {Node<E> newNode = new Node(element, null);newNode.next = head.next;//先让新添加的节点的下⼀个指向原head节点指向的 head.next = newNode;//再让head节点指向新节点}//尾插法public void addTail(E element) {Node<E> newNode = new Node(element, null);Node<E> tail = head;//定义⼀个节点从头⾛到尾//tail⾛到当前链表的尾部while (tail.next != null) {tail = tail.next;}tail.next = newNode;newNode.next=null;}/*** 固定位置插⼊⼀个节点* 判断参数合法性* 找到pos位置的前⼀个节点* @param pos 固定位置* @param element 元素*/public void addPos(int pos, E element) {if (pos <= 0 || pos > getLength()) {return;}Node<E> prev = head.next;int index = 1;while (index++ < pos - 1) {prev = prev.next;}Node<E> newNode = new Node<>(element, null);newNode.next = prev.next;prev.next = newNode;}//删除元素为element的节点public boolean remove(E element) {//如果只有⼀个头结点,返回falseif (head.next == null) {return false;}//找到该元素所对应的节点 + 该元素所对应的节点的前⼀个 //从头结点开始遍历Node<E> tmp = head;while (tmp != null) {if (tmp.next != null && tmp.next.data == element) {//tmp.next是我们要删除的节点 tmp是删除节点的前⼀个 tmp.next = tmp.next.next;return true;}tmp = tmp.next;}return false;}//设置某个位置的值为newElementpublic void set(int pos, E newElement){if(pos <= 0 || pos > getLength()){return;}//找pos位置的节点Node<E> tmp = head.next;for(int i=1; i < pos; i++){tmp = tmp.next;}tmp.data = newElement;}//得到某个元素的值public E get(E element){Node<E> tmp = head.next;//从有效节点开始遍历while(tmp != null){if(tmp.data == element){return tmp.data; //找到的话,返回该节点}tmp = tmp.next;}return null;} //合并两个有序的单链表public void merge(SingleLinekdListTakeHead<E> list2){// LinkedExercise<E> list3=new LinkedExercise<>();Node<E> p=this.head;//最后合并成功的的链表Node<E> p1=this.head.next;//第⼀的链表Node<E> p2=list2.head.next;//第⼆个链表while (p1!=null && p2!=null){if(pareTo(p2.data)>=0){p.next=p2;//list3.add(p2.data);p2=p2.next;}else {p.next=p1;// list3.add(p1.data);p1=p1.next;}p=p.next;}if(p1!=null){ //链表1还有剩余节点p.next=p1;}p.next=p2;}// return p.data;}//返回长度public int getLength() {Node<E> tmp = head.next;int length = 0;while (tmp != null) {length++;tmp = tmp.next;}return length;}//打印栈public String toString() {StringBuilder strs = new StringBuilder();Node<E> tmp = head.next;while (tmp != null) {strs.append(tmp.data + " ");tmp = tmp.next;}return strs.toString(); //strs是StringBuilder类型,应该添加toString⽅法,才能返回String类型的 }//逆置带有头结点的单链表public void reverse(){if(head.next==null||head.next.next==null){return;}else {Node<E> cur=this.head.next.next;//指向第⼆个有效的节点this.head.next.next=null;Node<E> pos=null;while (cur!=null){pos=cur.next;//先将cur.next指向poscur.next=head.next;head.next=cur;//头插法,将节点插在head后cur=pos;}}}}public class Linked {public static void main(String[] args) {SingleLinekdListTakeHead<Integer> list=new SingleLinekdListTakeHead();list.addHead(3);list.addHead(5);list.addHead(8);System.out.println(list.toString());//8 5 3list.addTail(1);list.addTail(2);list.addTail(4);System.out.println(list.toString());//8 5 3 1 2 4list.reverse();System.out.println(list.toString());// list.addPos(2, 100); //在2 号位置加⼊元素100// System.out.println(list.toString());// list.addPos(0, 1000);// System.out.println(list.toString());//// list.remove(4);// System.out.println("删除值为4的元素:"+list.toString());//// list.set(2,2);//true,把2号元素的值改为2// System.out.println("把2号元素的值改为2:"+list.toString());// System.out.println(list.get(3));SingleLinekdListTakeHead list1=new SingleLinekdListTakeHead();list1.addTail(2);list1.addTail(6);list1.addTail(7);SingleLinekdListTakeHead list2=new SingleLinekdListTakeHead();list2.addTail(3);list2.addTail(4);list2.addTail(5);list2.addTail(9);list2.addTail(10);list1.merge(list2);System.out.println(list1.toString());}}练习5:链式队列package Exercise;public class LinkedQueue<T> {private Entry<T> front;private Entry<T> rear;private int count;public LinkedQueue(){this.front=this.rear=new Entry<>(null,null);}class Entry<T>{T data;Entry<T> next;public Entry(T data,Entry<T> next){this.data=data;this.next=next;}}public void offer(T data){Entry<T> node=new Entry<>(data,null);this.rear.next=node;this.rear=node;this.count++;}/***出队列需要判断队列空的情况,头节点⽆效;如果队列为空,需要将front和rear都指向空*/public void poll(){if(this.front.next!=null){this.front.next=this.front.next.next;if(this.front.next == null){this.rear = this.front;}this.count--;}}public int size(){return this.count;}public T peek(){return this.front.next.data;}public void show(){Entry<T> cur=this.front.next;while (cur!=null){System.out.print(cur.data+" ");cur=cur.next;}System.out.println();}public static void main(String[] args) {LinkedQueue l=new LinkedQueue();for (int i = 0; i < 4; i++) {l.offer(i);}l.show();System.out.println("队头元素为:"+l.peek());System.out.println("队列长度为:"+l.size());l.poll();l.show();}}难点:内部类和外部类的构造函数都需要对相应属性做初始化。
C、C++程序设计:链表单元测试与答案
一、单选题1、在一个单链表中,已知q所指结点是p所指结点的前驱结点,若在q和p之间插入结点s,则执行()。
A.s->next=p->next;p->next=s;B.p->next=s->next; s->next=p;C.p->next=s;s->next=q;D.q->next=s;s->next=p;正确答案:D2、在一个表头指针为HL单链表中,若要向表头插入一个由指针p 指向的结点,则执行( )。
A.p一>next=HL;HL=p;B.HL=p; p一>next=HL;C.p一>next=Hl; p=HL;D.p一>next=HL一>next; HL=p;正确答案:A3、在单链表指针为p的结点之后插入指针为s的结点,正确的操作是:()。
A.p->next=s->next;p->next=s;B.p->next=s;s->next=p->next;C.p->next=s;p->next=s->next;D.s->next=p->next;p->next=s;正确答案:D4、在表尾指针为rs的链表的后面插入指针为p的结点的正确语句为()。
A.p->next=NULL; rs=p;B.rs->next=p; p->next=NULL;C.rs->next=p; rs->next=NULL;D.p->next=rs; rs->next=NULL;正确答案:B5、假设p为表尾指针rs的前驱指针,则删除表尾结点的正确语句为()。
A.p->next=NULL; delete p;B.p->next=NULL; delete rs;C.p=NULL; delete rs;D.rs=NULL; delete rs;正确答案:B二、判断题1、链表存储时,各结点的存储空间可以是不连续的。
链表c语言经典例题
链表c语言经典例题
链表是计算机科学中的经典数据结构之一,常用于存储和操作动态数据。
以下是一些常见的链表例题,可以帮助理解链表的基本操作和应用。
1. 链表的创建:
- 创建一个空链表。
- 创建一个包含指定节点值的链表。
2. 链表的插入操作:
- 在链表的头部插入一个节点。
- 在链表的尾部插入一个节点。
- 在指定位置插入一个节点。
3. 链表的删除操作:
- 删除链表的头节点。
- 删除链表的尾节点。
- 删除指定数值的节点。
4. 链表的查找操作:
- 查找链表中指定数值的节点。
- 查找链表的中间节点。
5. 链表的逆序操作:
- 反转整个链表。
- 反转链表的前 N 个节点。
- 反转链表的一部分区间内的节点。
6. 链表的合并操作:
- 合并两个有序链表,使其有序。
- 合并 K 个有序链表,使其有序。
7. 链表的环检测:
- 判断链表中是否存在环,若存在,则返回环的起始节点。
8. 链表的拆分操作:
- 将一个链表按照奇偶位置拆分成两个链表。
以上是一些链表的经典例题,通过解答这些例题,可以加深对链表结构和基本操作的理解。
在编写对应的 C 语言代码时,需要注意链表节点的定义、指针的使用以及内存的动态分配和释放等问题。
C语言程序设计专项训练题之 单链表
计算机等级考试二级C语言程序设计专项训练题——单链表一.程序填空题1.给定程序的主函数中,已给出由结构体构成的链表结点a、b、c,各结点的数据域中均存入字符,函数fun的功能是:将a、b、c 三个结点链接成一个单向链表,并输出链表结点中的数据。
请在下划线处填入正确的内容并将下划线删除,使程序得出正确的结果。
注意:不得增行或删行,也不得更改程序的结构!#include <stdio.h>typedef struct list{char data;struct list *next;}Q;void fun(Q *pa, Q *pb, Q *pc){Q *p;/**********found**********/pa->next=___1___;pb->next=pc;p=pa;while( p ){/**********found**********/printf(" %c",____2_____);/**********found**********/p=____3____;}printf("\n");}int main(){Q a, b, c;a.data='E';b.data='F';c.data='G'; c.next=NULL;fun( &a, &b, &c );return 0;}2.给定程序中,函数fun的功能是:统计出带有头结点的单向链表中结点的个数,存放在形参n所指的存储单元中。
请在下划线处填入正确的内容并将下划线删除,使程序得出正确的结果。
注意:不得增行或删行,也不得更改程序的结构!#include <stdio.h>#include <stdlib.h>#define N 8typedef struct list{int data;struct list *next;} SLIST;SLIST *creatlist(int *a);void outlist(SLIST *);void fun( SLIST *h, int *n){SLIST *p;/**********found**********/___1___=0;p=h->next;while(p){(*n)++;/**********found**********/p=p->___2___;}}int main(){SLIST *head;int a[N]={12,87,45,32,91,16,20,48}, num;head=creatlist(a);outlist(head);/**********found**********/fun(___3___, &num);printf("\nnumber=%d\n",num);return 0;}SLIST *creatlist(int a[]){SLIST *h,*p,*q;int i;h=p=(SLIST *)malloc(sizeof(SLIST));for(i=0; i<N; i++){q=(SLIST *)malloc(sizeof(SLIST));q->data=a[i]; p->next=q; p=q;}p->next=0;return h;}void outlist(SLIST *h){SLIST *p;p=h->next;if (p==NULL) printf("The list is NULL!\n");else{printf("\nHead ");do{printf("->%d",p->data);p=p->next;} while(p!=NULL);printf("->End\n");}}3.给定程序中,函数fun的功能是:计算出带头结点的单向链表中各结点数据域之和作为函数值返回。
链表练习题及答案
1、已知L是带表头的单链表,其P结点既不是首元结点,也不是尾元结点,a.删除p结点的直接后继的语句是11,3,14b.删除p结点的直接前驱的语句是10,12,8,11,3,14c.删除p结点的语句序列是10,7,3,14d.删除首元结点的语句序列是12,10,13,14e.删除尾元结点的语句序列是9,11,3,14(1)p=p->next;(2) p->next=p;(3)p->next=p->next->next;(4)p=p->next->next;(5)while(p)p=p->next;(6)whlie(Q->next){p=Q;Q=Q->next;}(7)while(p->next!=Q)p=p->next;(8)while(p->next->next!=Q)p=p->next;(9)while(p->next->next)p=p->next;(10)Q=p;(11)Q=p->next;(12)p=L;(13)L=L->next;(14)free(Q);2、已知L是带表头的单链表,其P结点既不是首元结点,也不是尾元结点,a.在p结点后插入s结点的语句序列是4,1b.在p结点前插入s结点的语句序列是7,11,8,4,1c.在表首插入s结点的语句序列是5,12d.在表尾插入s结点的语句序列是7,9,4,1或11,9,1,61.p-> next =s;2.p-> next=p-> next-> next;3.p->next=s->next;4.s->next=p-> next;5.s-> next=L;6.s->next=NULL;7.q=p ;8.while(p->next!=q) p=p->next;9.while(p->next!=NULL) p=p->next;10.p =q;11.p=L;12.L=s;13.L=P;3、已知P结点是某双向链表的中间结点,从下列提供的答案中选择合适的语句序列a.在P结点后插入S结点的语句序列是12,7,3,6b.在P结点前插入S结点的语句序列是13,8,5,4c.删除p结点的直接后继结点的语句序列是15,1,11,18d.删除p结点的直接前驱结点的语句序列是16,2,10,18e.删除p结点的语句序列是9,14,171.P->next=P->next->next;2.P->priou=P->priou->priou;3.P->next=S;4.P->priou=S;5.S->next=P;6.S->priou=P;7.S->next=P->next;8.S->priou=P->priou;9.P->priou->next=P->next;10.P->priou->next=P;11.P->next->priou=P;12.P->next->priou=S;13.P->priou->next=S;14.P->next->priou=P->priou;15.Q=p->next;16.Q=P->priou;17.free(P);18.free(Q);。
链表算法例题及练习
单链表算法练习(一)上节课思考问题:1、链表的特点是什么?2、结点、数据域、指针域?3、单链表、双链表、多链表、循环链表?4、头指针、头结点?5、在链表中设置头结点的好处?算法1:创建单链表(头插法,课本算法2.11)void CreateList(参数列表) Linklist &L, int n {第一步:开辟头结点,使其成为一个空单链表L=Malloc(sizeof(Lnode));L->next=NULL;第二步:依次创建新结点For(i=n;i>0;i--)开辟新结点P=Malloc(sizeof(Lnode));赋值Scanf(&P->data);使其成为后一结点P->next=L->next;插入到表头L->next=p;}算法2:查找(返回第i个元素的值,课本算法2.8)status GetElem_L(参数列表) LinkList L, int i, ElemType &e{第一步:初始化,从第一个结点开始P=L->next;J=1;第二步:顺序向后查找,直到表尾或找到第i个元素While(!p && j>i ){P=p->next;J++}第三步:判断是否找到该元素(没有,返回ERROR;有,将其存放于指定元素)If(!p || j>i) return ERROR;E=p->data;第四步:返回OKreturn OK;}单链表思考练习题一:1、用单链表结构来存放26个英文字母组成的线性表(a,b,c,…,z),请写出C语言程序。
难点分析:每个数据元素在内存中是“零散”存放的,其首地址怎么找?又怎么一一链接?实现思路:先开辟头指针,然后陆续为每个数据元素开辟存储空间并赋值,并及时将地址送给前面的指针。
2、思考尾插法创建单链表的算法。
3、分析课本算法2.9和2.10。
数据结构-C语言版:单链表例题
delmax是用类程序设计语言描述的,删除带表 头结点的单链表 lk 中数据域值最大的结点的算法。 链表中的结点 node 包括一个整型数据域 data 和一 个指向后继结点的指针 域 next,如图所示。
data next
lk
node
类程序设计语言描述形式 p 指向的结点的数据域用 p^.data表示、指针域用 p^. next 表示。算法中,“←”为赋值号,nil 为空指 针。
据域值最大结点的
(前
{ m←p^.data;
驱结点或后继结点)。
(3); } q←p; p←p^.next }
6)若算法中的链表是循环单链表,
则程序中的“p<>nil”这个条件应
改为
。
7)设 lk 单链表中的结点数据域值
q←r^.next;
依次为 3,1,7,5,4,则程序执
(4); dispose(q)
Algorithm delmaxl(lk) //lk 为单链表的头指针//
{ r←lk;
// m 为整型量//
p←lk^. next;
//p,q,r 为辅助指针//
if p<>nil
{ m←p^.data;
(1);
p←p^.next;
while p<>nil
{ if
(2)
回答以下问题:
5)该算法中的 r 变量最终指向数
行结束时,m=
。
}
}
参考答案
(1) q←p (2) p^.data>m (3) r←q (4) r^.next←q^.next (5) 前驱结点 (6) p!=lk (7) 7
C语言链表题目及答案
下面哪种选项描述了链表的特点?A) 可以随机访问元素B) 拥有固定大小的内存空间C) 元素之间通过指针连接D) 可以自动调整大小答案: C在链表中,头节点的作用是什么?A) 存储链表的长度B) 存储链表的最后一个节点C) 存储链表的第一个节点D) 存储链表的中间节点答案: C下面哪种选项描述了双向链表的特点?A) 每个节点只有一个指针指向下一个节点B) 每个节点只有一个指针指向上一个节点C) 每个节点同时拥有指向前一个节点和后一个节点的指针D) 只能从链表的一端进行操作答案: C在链表中,删除一个节点的操作涉及修改哪些指针?A) 只需要修改被删除节点的前一个节点的指针B) 只需要修改被删除节点的后一个节点的指针C) 需要修改被删除节点的前一个节点和后一个节点的指针D) 不需要修改任何指针答案: C在链表的尾部添加一个新节点的操作复杂度是多少?A) O(1)B) O(n)C) O(log n)D) O(n^2)答案: A如何遍历链表的所有节点?A) 使用for循环B) 使用while循环C) 使用递归函数D) 使用if语句答案: B在链表中,如何找到特定值的节点?A) 使用线性搜索B) 使用二分搜索C) 使用递归搜索D) 使用栈搜索答案: A链表和数组相比,哪个更适合频繁插入和删除操作?A) 链表B) 数组C) 二叉树D) 堆栈答案: A在链表中,如何在指定位置插入一个新节点?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 不需要修改任何指针答案: A链表的头指针指向什么?A) 链表的第一个节点B) 链表的最后一个节点C) 链表的中间节点D) 链表的空节点答案: A链表中节点的个数称为什么?A) 链表的长度B) 链表的高度C) 链表的宽度D) 链表的容量答案: A在链表中,如何删除指定值的节点?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 不需要修改任何指针答案: A单链表的最后一个节点指向什么?A) 链表的第一个节点B) 链表的最后一个节点C) NULLD) 链表的中间节点答案: C双向链表相比于单向链表的优势是什么?A) 占用更少的内存空间B) 遍历速度更快C) 可以从任意方向遍历D) 插入和删除操作更快答案: C在链表中,如何找到倒数第n个节点?A) 遍历整个链表B) 使用递归函数C) 使用栈数据结构D) 使用双指针技巧答案: D链表的删除操作和数组的删除操作的时间复杂度分别是什么?A) 链表的删除操作为O(1),数组的删除操作为O(n)B) 链表的删除操作为O(n),数组的删除操作为O(1)C) 链表的删除操作为O(n),数组的删除操作为O(n)D) 链表的删除操作为O(1),数组的删除操作为O(1)答案: A在链表中,如何判断链表是否为空?A) 检查头指针是否为NULLB) 检查尾指针是否为NULLC) 检查链表的长度是否为0D) 检查链表的第一个节点是否为NULL答案: A链表的逆序操作是指什么?A) 删除链表中的节点B) 反转链表中节点的顺序C) 插入节点到链表的尾部D) 在链表中查找指定值的节点答案: B在链表中,如何查找指定值的节点?A) 使用线性搜索B) 使用二分搜索C) 使用递归搜索D) 使用栈搜索答案: A在双向链表中,如何删除指定值的节点?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 不需要修改任何指针答案: A链表的插入操作和数组的插入操作的时间复杂度分别是什么?A) 链表的插入操作为O(1),数组的插入操作为O(n)B) 链表的插入操作为O(n),数组的插入操作为O(1)C) 链表的插入操作为O(n),数组的插入操作为O(n)D) 链表的插入操作为O(1),数组的插入操作为O(1)答案: A如何删除单向链表中的重复节点?A) 使用递归算法B) 使用双指针技巧C) 使用栈数据结构D) 不需要额外操作,链表会自动去重答案: B链表的优势之一是什么?A) 随机访问速度快B) 占用内存空间少C) 插入和删除操作高效D) 支持高级操作如排序和搜索答案: C在链表中,如何找到中间节点?A) 遍历整个链表B) 使用递归函数C) 使用栈数据结构D) 使用快慢指针技巧答案: D在链表中,如何在尾部添加一个新节点?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 创建一个新节点并更新尾指针答案: D链表的查找操作的时间复杂度是多少?A) O(1)B) O(log n)C) O(n)D) O(n^2)答案: C在双向链表中,如何找到倒数第n个节点?A) 从头节点开始遍历B) 从尾节点开始遍历C) 使用递归函数D) 使用双指针技巧答案: B链表的删除操作的时间复杂度是多少?A) O(1)B) O(log n)C) O(n)D) O(n^2)答案: A链表和数组相比,哪个更适合频繁插入和删除操作?A) 链表B) 数组C) 哈希表D) 栈答案: A如何判断链表是否有环?A) 使用线性搜索B) 使用递归算法C) 使用快慢指针技巧D) 使用栈数据结构答案: C在链表中,如何反转链表的顺序?A) 使用递归算法B) 使用栈数据结构C) 使用双指针技巧D) 使用循环迭代答案: D在链表中,如何删除所有节点?A) 依次删除每个节点B) 修改头指针为NULLC) 修改尾指针为NULLD) 不需要额外操作,链表会自动清空答案: A链表的头节点是什么?A) 链表的第一个节点B) 链表的最后一个节点C) 链表的中间节点D) 链表的空节点答案: A在链表中,如何插入一个新节点到指定位置之前?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 不需要修改任何指针答案: A在链表中,如何删除指定位置的节点?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 不需要修改任何指针答案: A单向链表和双向链表的区别是什么?A) 单向链表只有一个指针指向下一个节点,双向链表有两个指针分别指向前一个节点和后一个节点B) 单向链表只能从头到尾遍历,双向链表可以从头到尾或者从尾到头遍历C) 单向链表只能在尾部添加节点,双向链表可以在头部和尾部都添加节点D) 单向链表只能包含整型数据,双向链表可以包含任意类型的数据答案: A链表的删除操作和数组的删除操作的时间复杂度分别是什么?A) 链表的删除操作为O(1),数组的删除操作为O(n)B) 链表的删除操作为O(n),数组的删除操作为O(1)C) 链表的删除操作为O(n),数组的删除操作为O(n)D) 链表的删除操作为O(1),数组的删除操作为O(1)答案: A如何判断两个链表是否相交?A) 比较链表的长度是否相等B) 比较链表的头节点是否相等C) 比较链表的尾节点是否相等D) 比较链表中的所有节点是否相等答案: B链表和数组的主要区别是什么?A) 链表是一种线性数据结构,数组是一种非线性数据结构B) 链表的长度可变,数组的长度固定C) 链表支持随机访问,数组只能顺序访问D) 链表的插入和删除操作效率高,数组的访问效率高答案: B在链表中,如何找到倒数第k个节点?A) 从头节点开始遍历,直到倒数第k个节点B) 从尾节点开始遍历,直到倒数第k个节点C) 使用递归函数查找倒数第k个节点D) 使用双指针技巧,一个指针先移动k步,然后两个指针同时移动直到第一个指针到达链表末尾答案: D在链表中,如何判断是否存在环?A) 使用线性搜索,检查是否有重复的节点B) 使用递归算法,判断节点是否已经访问过C) 使用栈数据结构,检查节点是否已经入栈D) 使用快慢指针技巧,如果两个指针相遇,则存在环答案: D如何将两个有序链表合并成一个有序链表?A) 创建一个新链表,依次比较两个链表的节点并插入新链表中B) 将第一个链表的尾节点指向第二个链表的头节点C) 将第二个链表的尾节点指向第一个链表的头节点D) 使用递归算法,依次比较两个链表的节点并合并答案: A在链表中,如何删除重复的节点?A) 使用递归算法,遍历链表并删除重复的节点B) 使用双指针技巧,依次比较相邻节点并删除重复的节点C) 使用栈数据结构,检查节点是否已经入栈并删除重复的节点D) 不需要额外操作,链表会自动去重答案: B链表的优点是什么?A) 占用内存空间少B) 插入和删除操作高效C) 支持高级操作如排序和搜索D) 可以随机访问任意位置的元素答案: B。
c语言练习题6(数组与链表,有答案)
1、(1)数据结构中,与所使用的计算机无关的是数据的_C_______。
A)存储结构B)物理结构C)逻辑结构D)物理和存储结构评析:数据结构概念一般包括3个方面的内容,数据的逻辑结构、存储结构及数据上的运算集合。
数据的逻辑结构只抽象的反映数据元素之间的逻辑关系,而不管它在计算机中的存储表示形式。
2、栈底至栈顶依次存放元素A、B、C、D,在第五个元素E入栈前,栈中元素可以出栈,则出栈序列可能是____D____。
A)ABCED B)DBCEA C)CDABE D)DCBEA评析:栈操作原则上“后进先出”,栈底至栈顶依次存放元素A、B、c、D,则表明这4个元素中D是最后进栈,B、c处于中间,A最早进栈。
所以出栈时一定是先出D,再出c,最后出A。
3、线性表的顺序存储结构和线性表的链式存储结构分别是____B____。
A)顺序存取的存储结构、随机存取的存储结构B)随机存取的存储结构、顺序存取的存储结构C)随机存取的存储结构、随机存取的存储结构D)任意存取的存储结构、任意存取的存储结构评析:顺序存储结构中,数据元素存放在一组地址连续的存储单元中,每个数据元素地址可通过公式LOC(ai)。
LOC(a1)+(i-1)L计算得到,从而实现了随机存取。
对于链式存储结构,要对某结点进行存取,都得从链的头指针指向的结点开始,这是一种顺序存取的存储结构。
4、在单链表中,增加头结点的目的是____A__。
A)方便运算的实现B)使单链表至少有一个结点C)标识表结点中首结点的位置D)说明单链表是线性表的链式存储实现评析:头结点不仅标识了表中首结点的位置,而且根据单链表(包含头结点)的结构,只要掌握了表头,就能够访问整个链表,因此增加头结点目的是为了便于运算的实现。
5、数据处理的最小单位是___C_____。
A)数据B)数据元素C)数据项D)数据结构评析:数据处理的最小单位是数据项;由若干数据项组成数据元素;而数据是指能够被计算机识别、存储和加工处理的信息载体;数据结构是指数据之间的相互关系和数据运算。
C++语言第3章习题(链表)
单链表的结点类(ListNode class)和链表类(List class)的类定义。
template <class Type> class List;//前视的类定义template <class Type> class ListNode {//链表结点类的定义friend class List<Type>;//List类作为友元类定义private:Type data;//数据域ListNode<Type> *link;//链指针域public:ListNode ( ) : link (NULL) { }//仅初始化指针成员的构造函数ListNode ( const Type& item ) : data (item), link (NULL) { }//初始化数据与指针成员的构造函数ListNode<Type> * getNode ( const Type& item, ListNode<Type> *next = NULL )//以item和next建立一个新结点ListNode<Type> * getLink ( ) { return link;} //取得结点的下一结点地址Type getData ( ) { return data; }//取得结点中的数据void setLink ( ListNode<Type> * next ) { link = next; }//修改结点的link指针void setData ( Type value ) { data = value; } //修改结点的data值};template <class Type> class List {//单链表类定义private:ListNode<Type> *first, *current;//链表的表头指针和当前元素指针public:List ( const Type& value ) { first = current = new ListNode<Type> ( value ); }//构造函数~List ( ) { MakeEmpty ( ); delete first; }//析构函数void MakeEmpty ( );//将链表置为空表int Length ( ) const;//计算链表的长度ListNode<Type> * Find ( Type value ); //搜索含数据value的元素并成为当前元素ListNode<Type> * Locate( int i ); //搜索第i个元素的地址并置为当前元素Type *GetData ( );//取出表中当前元素的值int Insert ( Type value ); //将value插在表当前位置之后并成为当前元素Type *Remove ( );//将链表中的当前元素删去, 填补者为当前元素ListNode<Type> * Firster ( ) { current = first; return first; }//当前指针定位于表头结点Type *First ( );//当前指针定位于表中第一个元素并返回其值Type *Next ( );//将当前指针进到表中下一个元素并返回其值int NotNull ( ) {return current != NULL; } //表中当前元素空否?空返回1, 不空返回0int NextNotNull ( ) {return current != NULL && current->link != NULL; }//当前元素下一元素空否?空返回1, 不空返回0 };3-1线性表可用顺序表或链表存储。
习题3(链表)
习题3(链表)一、选择题(1)链接存储的存储结构所占存储空间( A )。
A)分两部分,一部分存放结点值,另一部分存放表示结点间关系的指针B)只有一部分,存放结点值C)只有一部分,存储表示结点间关系的指针D)分两部分,一部分存放结点值,另一部分存放结点所占单元数(2)线性表若采用链式存储结构时,要求内存中可用存储单元的地址( D )。
A)必须是连续的B)部分地址必须是连续的C)一定是不连续的D)连续或不连续都可以(3)线性表L在( B )情况下适用于使用链式结构实现。
A)需经常修改结点值B)需不断删除插入C)含有大量的结点D)结点结构复杂(4)单链表的存储密度( C )。
A)大于1 B)等于1 C)小于1 D)不能确定(5)若指定有n个元素的向量,则建立一个有序单链表的时间复杂性的量级是( C )。
A)O(1) B)O(n) C)O(n2) D)O(nlog2n)(6)在单链表中,要将s所指结点插入到p所指结点之后,其语句应为( D )。
A)s->next=p+1; p->next=s; B)(*p).next=s; (*s).next=(*p).next;C)s->next=p->next; p->next=s->next; D)s->next=p->next; p->next=s;(7)在双向链表存储结构中,删除p所指的结点时须修改指针( A )。
A)p->next->prior=p->prior; p->prior->next=p->next;B)p->next=p->next->next; p->next->prior=p;C)p->prior->next=p; p->prior=p->prior->prior;D)p->prior=p->next->next; p->next=p->prior->prior;(8)在双向循环链表中,在p指针所指的结点后插入q所指向的新结点,其修改指针的操作是( C )。
第三章 链表 基本题
第三章链表基本题3.2.1单项选择题1.不带头结点的单链表head为空的判定条件是A.head=NULLB.head->next=NULLC.head->next=headD.head!=NULL2.带头接待点的单链表head为空的判定条件是A.head=NULLB.head->next=NULLC.head->next=headD.head!=NULL3.非空的循环单链表head的尾结点(由p所指向)满足A.p->head=NULLB.p=NULLC.p->next=headD.p=head4.在循环双链表p的所指结点之后插入s所指结点的操作是A.p->right=s; s->left=p; p->right->lefe=s; s->right=p->right;B.p->right=s; p->right->left=s; s->lefe=p; s->right=p->right;C.s->lefe=p; s->right=p->right; p->right=s; p->right->left=s;D.s->left=p; s->right=p->right; p->right->left=s; p->right=s;5.在一个单链表中,已知q所指结点是所指结点p的前驱结点,若在q和p之间插入结点S,则执行A.s->next=p->next; p->next=s;B.p->next=s->next; s->next=p;C.q->next=s; s->next=p;D.p->next=s; s->next=q;6.在一个单链表中,若p所指结点不是最后结点,在p之后插入s所指结点,则执行A.s->next=p; p->next=s;B.s->next=p->next; p->next=s;C.s->next=p->next; p=s;D.p->next=s; s->next=p;7.在一个单链表中,若删除p所指结点的后续结点,则执行A.p->next=p->next->next;B.p=p->next; p->next=p->next->next;C.p->next=p->nextD.p=p->next->next8.假设双链表结点的类型如下:typedef struct linknode{int data; /*数据域*/Struct linknode *llink; /*llink是指向前驱结点的指针域*/Struct linknode *rlink; /*rlink是指向后续结点的指针域*/}bnode下面给出的算法段是要把一个所指新结点作为非空双向链表中的所指结点的前驱结点插入到该双链表中,能正确完成要求的算法段是A.q->rling=p; q->llink=p->llink; p->llink=q;p->llink->rlink=q;B.p->llink=q; q->rlink=p; p->llink->rlink=q; q->llink=p->llink;C.q->llink=p->llink; q->rlink=p; p->llink->rlink=q; p->llink=q;D.以上都不对9.从一个具有n个结点的有序单链表中查找其值等于x结点时,在查找成功的情况下,需平均比较()个结点。
C语言链表类面试题
struct node{int data;struct node* next;};创建单链表的程序为:struct node* create(unsigned int n){//创建长度为n的单链表assert(n > 0);node* head;head = new node;head->next = NULL;cout << "请输入head节点的值(int型):"; cin >> head->data;if (n == 1){return head;}node* p = head;for (unsigned int i = 1; i < n; i++){node* tmp = new node;tmp->next = 0;cout << "请输入第" << i+1 << "个节点的值(int):";cin >> tmp->data;p->next = tmp;p = tmp;}return head;}问题1:链表逆置思想为:head指针不断后移,指针反向即可,代码为:void reverse(node*& head){if (head != NULL && head->next != NULL){node* p = head;node* q = head->next;p->next = NULL;while (q->next != NULL){head = q->next;q->next = p;p = q;q = head;}head->next = p;}return;}问题2:删除不知头结点链表的某个节点如果单向链表不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点?思想为:把这个节点的下一个节点的值复制给该节点,然后删除下一个节点即可。
c语言链表题目
c语言链表题目链表是一种常用的数据结构,也是C语言面试中常考的知识点之一。
本文将介绍一些常见的链表题目,并提供C语言的解答。
1. 单链表反转题目描述:给定一个单链表,将其反转。
解答:struct ListNode* reverseList(struct ListNode* head) { struct ListNode *p = head, *q = NULL, *r = NULL;while(p != NULL) {r = q;q = p;p = p->next;q->next = r;}return q;}2. 删除链表中的节点题目描述:给定一个单链表和一个目标值,删除链表中所有值为目标值的节点。
解答:struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode *p = head, *q = NULL;while(p != NULL) {if(p->val == val) {if(q == NULL) {head = head->next;} else {q->next = p->next;}} else {q = p;}p = p->next;}return head;}3. 合并两个有序链表题目描述:给定两个有序链表,将它们合并为一个有序链表。
解答:struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {struct ListNode *head = NULL, *tail = NULL;while(l1 != NULL && l2 != NULL) {if(l1->val < l2->val) { if(head == NULL) {head = tail = l1;} else {tail->next = l1;tail = tail->next;}l1 = l1->next;} else {if(head == NULL) {head = tail = l2;} else {tail->next = l2;tail = tail->next;}l2 = l2->next;}}if(l1 != NULL) {if(head == NULL) {head = tail = l1;} else {tail->next = l1;tail = tail->next;}}if(l2 != NULL) {if(head == NULL) {head = tail = l2;} else {tail->next = l2;tail = tail->next;}}return head;}4. 判断链表是否有环题目描述:给定一个链表,判断它是否有环。
C语言链表实验题
{
/**********found**********/
r = q->__2__;
q->next = p;
p = q;
/**********found**********/
q = __3__ ;
}
return p;
}
NODE *creatlist(int a[])
{ NODE *h,*p,*q; int i;
fclose(out);
}
4.给定程序中,函数fun的功能是将不带头结点的单向链表逆置,即若原链表中从头至尾结点数据域依次为2,4,6,8,10.逆置后,从头至尾结点数据域依次为10,8,6,4,2.
#include <stdio.h>
#include <stdlib.h>
#define N 5
typedef struct node {
typedef struct list
{ int data;
struct list *next;
} SLIST;
SLIST *creatlist(char *);
void outlist(SLIST *);
int fun( SLIST *h, char ch)
{ SLIST *p; int n=0;
h=NULL;
for(i=0; i<N; i++)
{ q=(NODE *)malloc(sizeof(NODE));
q->data=a[i];
q->next = NULL;
if (h == NULL) h = p = q;
else { p->next = q; p = q; }
链表参考例题
1. 在D盘根目录中有两个数据文件Source1.dat和Source2.dat;2. 在Source1.dat和Source2.dat文件中以二进制方式分别存放了若干个用于表示工人的结构体类型数据。
结构体的声明如下:struct Worker{int num; //工号char name[10]; //姓名int age; //年龄int sex; //性别(0-男1-女)float salary; //工资};3. 编写一个函数,将Source1.dat文件中的数据读出,并且构建1个工人链表;4. 编写一个函数,显示上述第3步中生成的链表中的所有工人信息,每个工人的数据占一行,显示内容和格式要求如下:上述示意内容中斜体和线条部分仅用于说明题意的说明信息,不需要实际显示出来。
5. 编写一个函数,将上述第3步中生成的链表按照工号从大到小的顺序进行排序。
然后显示排序操作完成后链表中的所有工人信息,格式和第4步中相同。
6. 编写一个函数,删除上述第5步中生成的链表中年龄小于40岁的男性工人和工号大于650的女性工人。
然后显示删除操作完成后链表中的所有工人信息,格式和第4步中相同。
7. 编写一个函数,将Source2.dat文件中的数据依次读出,并且将所读出的每个工人数据依次插入到经过第6步处理后的工人链表中,要求仍然保持链表中工人工号的降序排列。
然后显示插入操作完成后链表中的所有工人信息,格式和第4步中相同。
8. 编写一个函数,求出经过第7步处理后的链表中所有年龄大于30岁的男性工人的平均工资,以及工资小于3000元的女性工人的最大年龄。
并在主函数中将所要求的计算结果显示在屏幕上,每个结果占一行。
注意:计算结果的显示必须安排在主函数中进行!9. 编写一个函数,对经过第7步处理的链表中全部工人数据保存到D盘根目录中的文本文件res.txt中,每个工人的数据占一行。
输出内容和格式和上述第4中要求相同。
c语言链表大例题
c语言链表大例题#include#include#include#include#define TRUE 1#define FALSE 0#define INPUT 1#define SHOW 2#define REMOVE 3#define INSERT 4#define SORT 5#define REV ANGE 6#define EXIT 7typedef struct POINT{int x, y; //x和y分别存储点的横、纵坐标值struct POINT *next; //next用以指向下一个同类实例(节点)}POINT;POINT *InputPoints(void);void showPointLink(POINT *head);void showOnePoint(POINT);void destroyLink(POINT *head);POINT *searchPrePoint(POINT *head, int x, int y);int removePoint(POINT **head);void sortPointByX(POINT *head);POINT *revangePointLink(POINT *head);void insertPoint(POINT **head);void showMenu(void);int selectedAction(void);void sayGoodBye(void);void sayGoodBye(void){int i;printf("\n\n\n\n\n\n");for(i = 0; i < 3; i++){printf(" 欢迎您的使用!\n按任意键继续...\n"); getch();printf(" 请您多提宝贵意见!\n按任意键继续...\n"); getch();printf(" 祝您身体健康!\n按任意键继续...\n"); getch();printf(" 谢谢使用!\n按任意键继续...\n");getch();printf(" 不送了!\n按任意键继续...\n");getch();printf(" 请您走好!\n按任意键继续...\n");getch();printf(" 不要忘了我哦\n按任意键继续...\n"); getch();printf(" 再见!\n按任意键继续...\n");getch();}}int selectedAction(void){int choose = 0;while(choose < 1 || choose > 7){showMenu();choose = getche();if(choose < '1' || choose > '7')choose = 0;elsechoose -= '0';if(choose == 0){printf("\n 输入错误!");printf("\n 请重新选择(1-7)");getch();}}return choose;}void showMenu(void){system("cls");printf("\n\n 屏幕上的点点的管理信息系统\n"); printf("\n 1)录入信息");printf("\n 2)显示信息");printf("\n 3)删除信息");printf("\n 4)插入信息");printf("\n 5)排序");printf("\n 6)逆序");printf("\n 7)退出");printf("\n 请选择:"); }void insertPoint(POINT **h){int Newx, Newy, Oldx, Oldy; POINT *p, *q;printf("插入前:"); showPointLink(*h);// 1、确定新点坐标;printf("请输入新点坐标:");scanf("%d%d", &Newx, &Newy);p = (POINT *)malloc(sizeof(POINT)); p->x = Newx;p->y = Newy;p->next = NULL;// 2、确定插入点坐标;printf("再输入插入点坐标:");scanf("%d%d", &Oldx, &Oldy);// 3、查找插入点的前驱节点;q = searchPrePoint(*h, Oldx, Oldy); // 4、插入节点。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
printf("插入后:");
showPointLink(*h);
}
POINT *revangePointLink(POINT *h)
{
POINT *p, *q;
printf("逆序前:");
showPointLink(h);
if(h)
{
p = h;
h = h->next;
p->next = NULL;
choose = 0;
else
choose -= '0';
if(choose == 0)
{
printf("\n输入错误!");
printf("\n请重新选择(1-7)");
getch();
}
}
return choose;
}
void showMenu(void)
{
system("cls");
printf("\n\n屏幕上的点点的管理信息系统\n");
printf("请输入一个点的两个坐标");
printf("任意坐标值为0,则表示输入结束\n");
scanf("%d%d", &x, &y); //先从键盘输入一对坐标
while(x && y) //只要有一个为0loc(sizeof(POINT));
void showPointLink(POINT *head);
void showOnePoint(POINT);
void destroyLink(POINT *head);
POINT *searchPrePoint(POINT *head, int x, int y);
int removePoint(POINT **head);
//是POINT,而当前函数相关内容是h,而其类型是POINT *,需要将POINT *
//转换成POINT类型,因此需要对h进行指向运算,以取得其所指向的实例。
printf("\n");
}
POINT *InputPoints(void)
{
int x, y;
POINT *head = NULL, *p, *q;
while(h)
{
q = h;
h = h->next;
q->next = p;
p = q;
}
}
printf("逆序后:");
showPointLink(p);
return p;
}
void sortPointByX(POINT *h)
{
POINT *p, *q, t, *r;
printf("\n排序前的结果是:");
getch();
break;
case REMOVE:
if(removePoint(&Head) == FALSE)
printf("删除的点不存在!");
printf("删除完毕!\nPress any key to continue...");
printf("\n 1)录入信息");
printf("\n 2)显示信息");
printf("\n 3)删除信息");
printf("\n 4)插入信息");
printf("\n 5)排序");
printf("\n 6)逆序");
printf("\n 7)退出");
printf("\n请选择:");
showPointLink(h);
printf("\n");
for(p = h; p; p = p->next)
for(q = p->next; q; q = q->next)
if(p->x > q->x)
{
t = *p;
*p = *q;
*q = t;
r = p->next;
p->next = q->next;
}
void insertPoint(POINT **h)
{
int Newx, Newy, Oldx, Oldy;
POINT *p, *q;
printf("插入前:");
showPointLink(*h);
// 1、确定新点坐标;
printf("请输入新点坐标:");
scanf("%d%d", &Newx, &Newy);
执行1号。*/
scanf("%d%d", &x, &y); //从键盘输入一对坐标
}
return head;//从前面的描述中可知,若head指向第一个节点,则
//返回该节点的首地址,就等于返回链表首地址;若一开始输入的
//数据中包含0,则head的初始值为NULL,此时返回值为NULL。
}
void main(void)
3、上述条件都不满足:成功的返回了要找节点的前驱节点。
*/
}
void destroyLink(POINT *h)
{
POINT *p;
while(h)
{
p = h; //让p指向h所指向的节点;
h = h->next; //让h向后移动;
free(p); //释放p所指向的节点;
}
}
void showOnePoint(POINT node)
printf("祝您身体健康!\n按任意键继续...\n");
getch();
printf("谢谢使用!\n按任意键继续...\n");
getch();
printf("不送了!\n按任意键继续...\n");
getch();
printf("请您走好!\n按任意键继续...\n");
getch();
printf("不要忘了我哦!!!\n按任意键继续...\n");
p = (POINT *)malloc(sizeof(POINT));
p->x = Newx;
p->y = Newy;
p->next = NULL;
// 2、确定插入点坐标;
printf("再输入插入点坐标:");
scanf("%d%d", &Oldx, &Oldy);
//3、查找插入点的前驱节点;
2、查找该点的前驱节点;
3、删除该点。*/
int x, y, Ok = TRUE;
POINT *p, *q;
//1、输入要删除的点的坐标;
printf("\n\n\n这是删除功能\n原有点坐标如下:\n");
showPointLink(*h);
printf("\n请输入要删除的点的坐标:");
scanf("%d%d", &x, &y);
{
POINT *Head = NULL;
int choice = 0;
while(choice != 7)
{
choice = selectedAction();
system("cls");
switch(choice)
{
case INPUT:
if(Head) //表示该链表非空,应该先清空!
destroyLink(Head);
Head = InputPoints();
printf("录入完成!\nPress any key to continue...");
getch();
break;
case SHOW:
showPointLink(Head);
printf("显示完毕!\nPress any key to continue...");
/*由于下面的话,说明q现在正好指向最后一个节点,只要将刚刚申请的,p
所指向的节点链接到最后一个节点的后面,即可完成任务。*/
q = p;//2号
/*q每次都在本轮循环结束之前指向刚刚申请且刚刚链到链表的末尾的那个
新节点(简单地说,q总指向链表的最后一个节点。
上述的1号语句和2号语句的书写顺序与执行顺序不同,总是先执行2号,再
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<conio.h>
#define TRUE 1
#define FALSE 0
#define INPUT 1
#define SHOW 2
#define REMOVE 3
#define INSERT 4
{
printf("<%d, %d> ", node.x, node.y);
}
//showPointLink(Head);
void showPointLink(POINT *h)
{
printf("\n链表的内容如下:\n");
for(; h; h = h->next)
showOnePoint(*h);//此处,函数showOnePoint()需要的参数类型